vobcopy-1.2.0/0000775000175000017500000000000011213270754012231 5ustar robosrobosvobcopy-1.2.0/TODO0000644000175000017500000030647211213266544012735 0ustar robosrobosTODO: - if an iso is mounted loop-back then vobcopy is unable to find the /dev/ entry in /etc/mtab and resorts to /etc/fstab where something wrong is written - hence vobcopy doesn't find the device. A new command line option?! - continue if a part of the image is already there (from a previous try). Should be doable with the -b code. - "uname -m" on my machine, you would get: x86_64 (where I've changed the .../lib to .../lib64 in three places), then the program compiles cleanly DONE - some code to prognose when the rip will be ready. - check more return values of libdvdread calls. - when copying over an existing file/dir vobcopy makes some trouble (i.e. it asks to overwrite bla.vob, starts writing to bla.vob.partial and at the end isn't capable of overwriting bla.vob when it tries to move the .partial. - error handling with the errno and strerror function THOUGHT-ABOUT FEATURES - being able to specify - which title - which chapter - which angle - which language(s) - which subtitle(s) to copy - print the total playing time of that title use EPM to package vobcopy Users comments|bug-reports: only -i /dev/rdisk works on osx if user uses -i then (maybe) force vobcopy to use this dir and not check the device accordingly. BUGREPORTS: Perhaps a verification needs to be added, to catch the situations when the user specifies a non-existing directory? (and either create it or abort with "no such directory", instead of claiming there's no free space) Hello, i use vobcopy in the mirror manner (vobcopy -m) and since it works well in 5.8, i have to tell you that a bug has been introduced since. In 5.10 vobcopy -m generate error like that : "cannot seek at xxxxx", and finaly the result is not readable by xine, ogle or vlc. In fact it began to read the movie correctly, but at the first change of vob file, xine (or others) craches. Was ist festgestellt habe: 1. -i /mnt/cd hat nicht funktioniert, aber -i /dev/acd0. 2. -e hat keine Wirkung. Ich habe verschiedene Werte ausprobiert, um nur wenige MB zu kopieren, trotzdem hat vobcopy weiter kopiert. Ich habe FreeBSD 5.2. Bug reporten. Zumindest bei mir geht die Fortschrittsanzeige nicht ganz bis auf 100%, selbst wenn schon die naechste Datei angefangen wird, sondern bleibt kurz davor stehen. Der letzte Schritt wird also nicht mehr angezeigt. grafisches frontend mit dem was knoppix-install macht (knx-hddinstall) ---------------------------------------------------------------------- CHECKED Adam Blazczak Here's the account of my experiences with compiling vobcopy-1.0.1 on Solaris 9, I hope you find the following information useful. $ uname -a SunOS solaris 5.9 Generic_118559-11 i86pc i386 i86pc configure.sh doesn't work at all.. it's not a biggie, as Makefile works mostly out of the box with minor adjustment (below) with gcc 3.4.6 $ ./configure.sh THIS CONFIGURE SCRIPT IS STILL HIGHLY EXPERIMENTAL! If you think you found a bug, please mail me, thanks! robos@muon.de ./configure.sh: test: argument expected Below are the code changes I needed to make it all compile properly. If you decide to add these to the repository, you might want to amend the changes (possibly make the addition of -lrt and inttypes.h conditional) to let the other platforms continue to compile without issues. Regards, Adam $ diff -u Makefile.orig Makefile --- Makefile.orig Sun Apr 15 19:16:29 2007 +++ Makefile Sun Apr 15 19:24:37 2007 @@ -11,7 +11,7 @@ MANDIR = ${PREFIX}/man LFS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE CFLAGS += -I/usr//include -LDFLAGS += -ldvdread -L/usr//lib +LDFLAGS += -ldvdread -lrt -L/usr//lib #This specifies the conversion from .c to .o $ diff -u vobcopy.h.orig vobcopy.h --- vobcopy.h.orig Sun Apr 15 18:42:47 2007 +++ vobcopy.h Sun Apr 15 19:05:41 2007 @@ -36,6 +36,7 @@ /*for/from play_title.c*/ #include /* #include "config.h" */ +#include #include #include #include @@ -61,8 +62,12 @@ # endif +#define off_t off64_t + #else /* Solaris */ +#define off_t __off64_t + /* ////////// *BSD ////////// */ #if ( defined( BSD ) && ( BSD >= 199306 ) ) @@ -170,8 +175,6 @@ #include "dvd.h" -#define off_t __off64_t - void usage(char *); -------------------------------------------------------------------------------------------------------------- From: Noah Maxwell To: Robos Subject: dvd_rip script on my website now Hey Robo's! I hope all is well with you. Just wanted to let you know I finally put my recent project script (dvd_rip.sh) on my website. It heavily uses vobcopy, and Ive gotton it to the point where it works pretty well, so I hope other people will find it useful as well. Please feel free to mirror it if you think anyone else might want to check it out: http://noahmaxwell.com/dvd/ Thanks! ------------------------------------------------------------------------------------------------------------- CHECK From: Dave Yeo building vobcopy-1.0.2 on OS/2 >> Lots of errors due to __off64_t not being declared, I added >> #if defined(__EMX__) >> #define __off64_t __int64_t >> #endif >> to vobcopy.h >> Then lots of errors like >> vobcopy.c:1569: error: `O_LARGEFILE' undeclared (first use in this >> function) >> vobcopy.c:1569: error: (Each undeclared identifier is reported only >> once >> vobcopy.c:1569: error: for each function it appears in.) >> >> since large files don't need to be flagged here. Also files should be >> opened in binary mode. I just removed the O_LARGEFILE flags though I'm >> sure there is a better way. >> Now I get this error which I don't know how to handle not being a >> programmer. >> c: In function `get_free_space': >> vobcopy.c:1799: error: storage size of `buf1' isn't known >> vobcopy.c: In function `get_used_space': >> vobcopy.c:1843: error: storage size of `buf2' isn't known >> make: *** [vobcopy.o] Error 1 > >Well, it looks like some header file isn't included. In linux it's >#include /* or */ (straight from the man-page). >In there the size of statfs should be declared. Can you look into that? >I just did a quick check on google but it looks like os/2 doesn't have that >function... But that was only a very superficial look. >Please take a look and if you find something get back to me. sys/vfs.h and sys/statfs.h are just here for Linux compatibility and just include sys/types.h and sys/mount.h. sys/mount.h is where statfs is declared but no members called buf1 or buf2. This is basically a standard (Free)BSD header. You can look at it here http://svn.netlabs.org/libc/browser/branches/libc-0.6/src/emx/include/sy s/mount.h -------------------------------------------------------------------------------------------------------------- CHECK From: Richard Handel Reply-To: richard@cbmc.co.uk To: Robos Subject: Re: Vobcopy bug report [-- Anhang #1 --] [-- Typ: text/plain, Kodierung: 7bit, Gr3,3K --] Hi Robos, I think you're right - I looked around, can't find any library function to do this. I've done an alternative fix, which is a patch to dvd.c (attached) - this one is better (more efficient), but they both work, so doesn't really matter. Not sure about UTF-8, I assumed it was just an ascii space char which has to be escaped in /etc/mtab (since a literal space would mean 'end of path') - but I'm guessing, & I've not looked into it too deeply. Cheers, Richard On 12/09/2007, Robos wrote: > On Mon, 10.09.07, Richard Handel wrote: > > Hi, > > Hi richard, > > > Just to let you know I found a minor bug in vobcopy, when I was doing > > a 'mirror copy'- it crashes when there is a space in the file name on > > the DVD. This is because /etc/mtab escapes spaces (they appear as > > '\040'), but opendir doesn't understand the name in that format. > > > > I've written a quick patch to vobcopy.c (diff attached for your info). > > I've tested it and it works (I'm using Linux, FC7), but it's not a > > proper fix, because: > > > > 1) maybe the fix should go in dvd.c, not vobcopy.c so it works for any > > call to get_device_on_your_own(). > > > > 2) maybe the path names in /etc/mtab can have other escape chars as > > well as spaces. > > > > 3) There's probably a library function to 'unescape' a string, but I > > don't know what it is. > > > > 4) There's already a loop in /get_device_on_your_own() which goes > > through all the characters in the path - maybe it would be more > > efficient to use that loop instead of creating a new one (but this > > depends if there's a library function to strip out the escapes). > > > > I don't know enough about the above points to do a proper fix, but I > > hope I've helped a bit if you decide you want to fix it properly. > > Huh, that's cool. I tripped about that myself 2 days ago. I don't know > either if there is already a library that does the un-escaping/spacing, but > I don't think so. I'll have a look at you patch and probably incorporate it, > I was too lazy to fight too long with c since I'm already getting rusty > again because of not using it that often :) > BTW: I think this is some unicode/UTF-8 thing... > Thanks a lot! > Cheers > Robos > > > Regards, > > > > Richard Handel > > > *** vobcopy.c.org 2007-09-10 16:03:42.000000000 +0100 > > --- vobcopy.c 2007-09-10 21:37:51.000000000 +0100 > > *************** > > *** 803,808 **** > > --- 803,816 ---- > > fprintf( stderr,"[Info] Writing files to this dir: %s\n", name ); > > } > > //TODO: substitute with open_dir function > > + /* START PATCH (Richard Handel, 10 Sept 07) unescape space characters in path */ > > + char* embedded_space = strstr(provided_input_dir, "\\040"); > > + while (embedded_space) { > > + *embedded_space = ' '; > > + strcpy(embedded_space + 1, embedded_space + 4); > > + embedded_space = strstr(provided_input_dir, "\\040"); > > + } > > + /* END PATCH (Richard Handel, 10 Sept 07) */ > > strcpy( video_ts_dir, provided_input_dir ); > > strcat( video_ts_dir, "video_ts"); /*it's either video_ts */ > > dir = opendir( video_ts_dir ); /*or VIDEO_TS*/ > > > -- > Robos - > gpg --recv-keys --keyserver blackhole.pca.dfn.de 6EEADA09 > > [-- Anhang #2: dvd.patch --] [-- Typ: text/x-patch, Kodierung: base64, Gr0,7K --] *** dvd.c.org 2007-09-13 00:57:34.000000000 +0100 --- dvd.c 2007-09-13 00:56:43.000000000 +0100 *************** *** 524,532 **** while(isgraph( (int) *(k) )) { ! path[l] = *(k); ! k++; ! l++; } path[l] = '\0'; --- 524,534 ---- while(isgraph( (int) *(k) )) { ! if (!strncmp(k, "\\040", 4)) { // replace escaped ASCII space ... ! path[l++] = ' '; // ... with literal space ! k+=4; ! } ! else path[l++] = *(k++); } path[l] = '\0'; --------------------------------------------------------------------------------------------------------------------- Ismail D (0,2K) Security problem(s) in vobcopy wegen cve -------------------------------------------------------------------------------------------------------------------- Bug#448319: opens /tmp/vobcopy.bla insecurely, symlink attack Changed Bug title to `CVE-2007-5718 insecure temporary file handling' from `opens /tmp/vobcopy.bla insecurely, symlink attack'. -------------------------------------------------------------------------------------------------------------------- From: Nico Golde To: Robos Subject: Re: security issue in vobcopy X-GPG: 0x73647cff X-RZG-AUTH: hvKiKtSHbeE0ghP2VIXOfz9FbKPIjAFDNRMtknfPuvqS60u3mcM1eRqaSnkWtRs= X-RZG-CLASS-ID: mo07 [-- PGP Ausgabe folgt (aktuelle Zeit: So 02 Dez 2007 23:13:15 CET) --] gpg: Signature made Di 06 Nov 2007 07:33:23 CET using DSA key ID 73647CFF gpg: Unterschrift kann nicht geprwerden: Schlnicht gefunden [-- Ende der PGP-Ausgabe --] [-- Die folgenden Daten sind signiert --] Hi Robos, * Robos [2007-11-06 07:20]: > On Mon, 05.11.07, Nico Golde wrote: > > did you see > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=448319 > > which is a security issue in vobcopy. > > Please read the following: > > https://www.securecoding.cert.org/confluence/display/seccode/TMP30-C.+Temporary+files+must+created+with+unique+and+unpredictable+file+names > > Someone from another distribution already made me away that someone thinks > this is a bug... > I'll try to fix "the problem" soon. Errm referring to your ironic tone you don't think this is an issue but you are wrong, it is ;) > Whom shall I contact with the new version? The maintainers for the distributions. It would be nice could contact me and Stephen Birch for Debian. Kind regards Nico ----------------------------------------------------------------------------------------------------------------------- CHECK Subject: Bug#451145: off-by-one error Reply-To: Nico Golde , 451145@bugs.debian.org Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: Stephen Birch X-Debian-PR-Message: report 451145 X-Debian-PR-Package: vobcopy X-Debian-PR-Keywords: patch X-Debian-PR-Source: vobcopy From: Nico Golde To: submit@bugs.debian.org X-GPG: 0x73647cff X-RZG-Auth: hvKiKtSHbeE0ghP2VIXOfz9FbKPIjAFDNRMtknfPuvqS60u3mcM1eRL0GjYHz1Y= X-RZG-Class-Id: mo07 X-PTS-Package: vobcopy X-PTS-Keyword: bts [-- PGP Ausgabe folgt (aktuelle Zeit: So 02 Dez 2007 23:14:21 CET) --] gpg: Signature made Di 13 Nov 2007 17:54:17 CET using DSA key ID 73647CFF gpg: Unterschrift kann nicht geprwerden: Schlnicht gefunden [-- Ende der PGP-Ausgabe --] [-- Die folgenden Daten sind signiert --] Package: vobcopy Version: 0.5.14-2 Severity: normal Tags: patch Hi, from vobcopy.c: 136 char dvd_path[255], logfile_name[20],logfile_path[255]; ... 473 strncpy( logfile_path, optarg, 255 ); 474 strcat( logfile_path, "/" ); This is an off-by-one. If optarg will consist of 255 characters strcat will write ony byte past the stack. The correct code would look like: strncpy(logfile_path, optarg, sizeof(logfile_path)-1); strcat(logfile_path, "/"); logfile_path[sizeof(logfile_path)-1] = '\0'; Kind regards Nico ----------------------------------------------------------------------------------------------------------------------- CHECK Looking at the vobcopy source code it turns out that there is a -L option to specify the logfile location, please add this to the manual. Kind regards Nico ---------------------------------------------------------------------------------------------------------------------- From: Jimmy Moore To: Robos Subject: Re: Vobcopy Hi Robos, Here is the forum post about it (Check out last line): http://www.usalug.org/phpBB2/viewtopic.php?t=9271&postdays=0&postorder=asc&&start=15&sid=7342fa91d35558b6782882b2ebab9000 Also from mplayer/mencoder manual: http://www.mplayerhq.hu/DOCS/HTML/en/faq.html#id2540533 I had an idea to use vobcopy, then when it failed, use mencoder, but the problem is that mencoder reads the whole title and combines everything into a single VOB file :( whereas I want the files from the DVD exactly as they were for menus etc. It does seem that dvdnav does get around the problems with Sony protection, which I believe is bad sectors or something. Also looks like dvdnav does all that dvdread does now, perhaps including some extra stuff. I've tried using 'ddrescue' to create an ISO image of the DVD, which it does successfuly but with errors. I'm not sure if pointing vobcopy at that ISO will work, but I may try that next Let me know what you think :) Regards Jimmy ------------------------------------------------------------------------------------------------------------------ From: Louis Granboulan Subject: Re: vobcopy on MacOS 10.4 To: Udo 'Robos' Puetz >Well, sure, but I at least need a way to figure out which version I'm >compiling on and #include and such accordingly. I don't know how to find it simply within gcc. Here is a rather dirty technique #include #if !defined(_POSIX_ASYNCHRONOUS_IO) /* MacOS 10.2 or before */ #elif _POSIX_VERSION == 198808L /* MacOS 10.3 */ #else /* MacOS 10.4 */ #endif Louis ------------------------------------------------------------------------------ From: Thiemo Gehrke To: Robos Subject: bug in vobcopy 1.0.0 Hallo, habe einen Bug gefunden: gibt man -q als Parameter an und ist ein Verzeichnes mit gleichem Namen schon vorhanden, schreibt vobcopy unentwegt "[Hint] please choose [c]ontinue or [q]uit the next time ;-)" in die /tmp/vobcopy.bla Und zwar so lange, bis das Dateisystem voll ist. Es fehlt also noch eine "always continue on error" option oder dergleichen. ich hoffe, ich bin nicht der 357. der das berichtet... gr Thiemo --------------------------------------------------------- From: "Jared P. Cordasco" To: robos@muon.de Subject: vobcopy bug report Reply-By: Oct 4 2005 12:00 -0500 [-- Anhang #1 --] [-- Typ: text/plain, Kodierung: quoted-printable, Gr2,0K --] Hi, I ran into a problem with vobcopy recently and I haven't had the time to poke around and send a patch with this bug report, but I could if you'd like. The problem is that vobcopy cannot handle very large hard drives for output. As you can see below I have such a drive, mostly free: Filesystem Size Used Avail Use% Mounted on /dev/hdb1 367G 50G 315G 14% /mnt/400 however running # vobcopy -o /mnt/400/backups/ -m yields: Vobcopy 1.0.1 - GPL Copyright (c) 2001 - 2006 robos@muon.de [Hint] All lines starting with "libdvdread:" are not from vobcopy but from the libdvdread-library [Info] Path to dvd: /dev/hdd [Info] Name of the dvd: RABBI_JACOB *** Zero check failed in ifo_read.c:432 for vmgi_mat->zero_3 = 0x00000000010000000000000000000000000000 [Info] There are 4 titles on this DVD. [Info] There are 15 chapters on the dvd. [Info] Most chapters has title 4 with 12 chapters. [Info] All titles: [Info] Title 1 has 1 chapter. [Info] Title 2 has 1 chapter. [Info] Title 3 has 1 chapter. [Info] Title 4 has 12 chapters. [Info] There are 4 angles on this dvd. [Info] All titles: [Info] Title 1 has 1 angle. [Info] Title 2 has 1 angle. [Info] Title 3 has 1 angle. [Info] Title 4 has 1 angle. [Info] DVD-name: RABBI_JACOB [Info] Disk free: -2099069 MB [Info] Vobs size: 3900 MB [Error] Not enough free space on the destination dir. Please choose another one or -f [Error] or dirs behind -1, -2 ... are NOT allowed with -m! However, when I append '-v -v' to get the log file, the log file is *different* than the above output in that it shows free disk space as 0MB. I've attached that log file. If you want, I'll poke around and send you a patch as I'm sure its simple enough to fix. Just let me know. ----------------------------------------------------------- From: Keith Brings Reply-To: ceo@noizu.biz To: robos@muon.de Subject: vobcopy quirks / and fixes. I just finished modifying your source to get everything to run on solaris express build 60 64bit. I only had to make a few minor tweaks but making a note of them might help simplify install for someone even newer to the *nix world than me.0 Make file: 1. On your make file the deb: entry stops the make with a "unexpected end of line" error. I just took the deb: section out and make ran find. 2. CC =? gcc also produced a crash, I'm not sure of the scripting syntax or what this was suppose to do but CC = gcc, or CC = cc works fine. source code. 3. dvd.c & vobcopy.c require #include Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. vobcopy-1.2.0/configure.sh0000755000175000017500000001612511213266544014556 0ustar robosrobos#!/bin/sh #hope this thing works across all systems, otherwise mail me please: #robos@muon.de echo "THIS CONFIGURE SCRIPT IS STILL HIGHLY EXPERIMENTAL! If you think you found a bug, please mail me, thanks! robos@muon.de" #This is the makefile generator for vobcopy, #The original makefile was written by rosenauer. These things #below here are variable definitions. They get substituted in the (CC) and #stuff places. #args check *new* #declare -i i=0 if [ $# != 0 ] then while [ $# != 0 ] do if [ "$1" != "${1#--prefix=}" ]; then prefix="${1#--prefix=}" prefix_provided=true echo "prefix = $prefix" fi if [ "$1" != "${1#--bindir=}" ]; then bindir="${1#--bindir=}" bindir_provided=true echo "bindir here: $bindir" fi if [ "$1" != "${1#--mandir=}" ]; then mandir="${1#--mandir=}" mandir_provided=true echo "with mandir here: $mandir" fi if [ "$1" != "${1#--docdir=}" ]; then docdir="${1#--docdir=}" docdir_provided=true echo "with docdir here: $docdir" fi if [ "$1" != "${1#--with-lfs}" ]; then echo "with large-file support" LFS="LFS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" lfs_provided=true fi if [ "$1" != "${1#--with-dvdread-libs=}" ]; then libs_dir="${1#--with-dvdread-libs=}" libs_dir_provided=true echo "with dvdread-libs here: $libs_dir" fi if [ "$1" != "${1%help}" ]; then echo "--prefix=PREFIX install architecture-independent files in PREFIX [/usr/local]" echo "--bindir=DIR user executables in DIR [PREFIX/bin]" echo "--mandir=DIR man documentation in DIR [PREFIX/bin]" echo "--docdir=DIR package documentation in DIR [PREFIX/share/doc/vobcopy]" echo "--with-dvdread-libs=DIR directory where dvdread lib (dvd_reader.h) is installed" echo "--with-lfs Enable large File System support" exit 1 fi shift 1 done fi if [ -z $prefix_provided ] then prefix=/usr/local fi if [ -z $mandir_provided ] then mandir=\${PREFIX}/man fi if [ -z $docdir_provided ] then docdir=\${PREFIX}/share/doc/vobcopy fi if [ -z $bindir_provided ] then bindir=\${PREFIX}/bin fi #see if libdvdread is installed if [ -z $libs_dir_provided ] then if [ ! -e /usr/local/include/dvdread ]; then if [ ! -e /usr/include/dvdread ]; then #muss hier das then hin?? echo "Do you have libdvdread installed? I (the script) can't find it" echo "You probably need the libdvdread-devel package or something similar installed. If you already have:" echo "Please provide the path to dvdreader.h after ./configure --with-dvdread-libs=" echo "And please mail me the location so that I can fix the makefile to robos@muon.de, thanks!" exit 1 else echo "libdvdread found" libs_dir=/usr/ # libs_dir=/usr/include fi else echo "libdvdread found" libs_dir=/usr/local/ # libs_dir=/usr/local/include fi else # Remove the following if...fi if the program complains about non-existing # headers when they really are there... if [ ! -e $libs_dir/include/dvdread ]; then echo "You specified that libdvdread is installed at $libs_dir. However" echo "I (the script) am unable to find the header files at" echo "$libs_dir/include/dvdread." echo "If they really are there, edit the configure.sh and remove" echo "this check." exit 1 fi fi #I hope this is a test to see if the system is largefile ready if [ -z $lfs_provided ] then if grep "ftello64" /usr/include/stdio.h >/dev/null 2>&1 then echo "largefile support found" LFS="LFS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" else echo "no large-file support found (by me, the stupid script)" echo "large file support is necessary if you want to output files larger than 2GB" echo "please append --with-lfs to ./configure, else lfs is disabled" LFS="LFS =" fi fi #FreeBSD needs libgnugetopt (kern.osreldate < 500041) #if [ `uname -s` = FreeBSD -a \ # `sysctl -n kern.osreldate 2> /dev/null` -lt 500041 ]; then if [ `uname -s` = FreeBSD ]; then if [ `sysctl -n kern.osreldate 2> /dev/null` -lt 500041 ]; then LDFLAGS="LDFLAGS += -ldvdread -L/usr/local/lib -lgnugetopt" else LDFLAGS="LDFLAGS += -ldvdread -L$libs_dir/lib" fi elif [ `uname -m` = x86_64 ]; then #for ia64/AMD64 libraries LDFLAGS="LDFLAGS += -ldvdread -L$libs_dir/lib64" else LDFLAGS="LDFLAGS += -ldvdread -L$libs_dir/lib" fi #Solaris 9 needs -lrt if [ `uname -a | grep "SunOS solaris 5.9" ` ]; then LDFLAGS="+LDFLAGS += -ldvdread -lrt -L/usr//lib" fi #see if a Makefile is present - and kill it ;-) if [ -e ./Makefile ]; then rm -f ./Makefile fi #write the Makefile touch Makefile echo " #This is the makefile for vobcopy, mainly written by rosenauer. These things #below here are variable definitions. They get substituted in the (CC) and #stuff places. DESTDIR = CC ?= gcc #PREFIX += /usr/local #BINDIR = \${PREFIX}/bin #MANDIR = \${PREFIX}/man PREFIX += $prefix BINDIR = $bindir MANDIR = $mandir DOCDIR = $docdir $LFS CFLAGS += -I$libs_dir/include $LDFLAGS #This specifies the conversion from .c to .o .c.o: \$(CC) \$(LFS) \$(CFLAGS) -c \$< #Here is implicitly said that for vobcopy to be made *.o has to be made first #make is kinda intelligent in that aspect. vobcopy: vobcopy.o dvd.o \$(CC) -o vobcopy vobcopy.o dvd.o \${LDFLAGS} disable_lfs: \$(CC) \$(CFLAGS) -c vobcopy.c \$(CC) \$(CFLAGS) -c dvd.c \$(CC) -o vobcopy vobcopy.o dvd.o -ldvdread debug: \$(CC) -c vobcopy.c -Wall -ggdb -pedantic \$(CFLAGS) \$(LFS) \$(CC) -c dvd.c -Wall -ggdb -pedantic \$(CFLAGS) \$(LFS) \$(CC) -o vobcopy vobcopy.o dvd.o -ldvdread deb: echo \"this here is really really experimental...\" dpkg-buildpackage -rfakeroot -us -uc -tc clean : rm -f vobcopy vobcopy.o dvd.o distclean : rm -f vobcopy.o dvd.o *~ install: # mkdir -p \$(MANDIR)/man1 # cp vobcopy \$(BINDIR)/vobcopy # cp vobcopy.1 \$(MANDIR)/man1/vobcopy.1 install -d -m 755 \$(DESTDIR)/\$(BINDIR) install -d -m 755 \$(DESTDIR)/\$(MANDIR)/man1 install -d -m 755 \$(DESTDIR)/\$(MANDIR)/de/man1 install -d -m 755 \$(DESTDIR)/\$(DOCDIR) install -m 755 vobcopy \$(DESTDIR)/\$(BINDIR)/vobcopy install -m 644 vobcopy.1 \$(DESTDIR)/\$(MANDIR)/man1/vobcopy.1 install -m 644 vobcopy.1.de \$(DESTDIR)/\$(MANDIR)/de/man1/vobcopy.1 install -m 644 COPYING Changelog README Release-Notes TODO \$(DESTDIR)/\$(DOCDIR) uninstall: rm -f \$(DESTDIR)/\$(BINDIR)/vobcopy rm -f \$(DESTDIR)/\$(MANDIR)/man1/vobcopy.1 rm -f \$(DESTDIR)/\$(MANDIR)/de/man1/vobcopy.1 rm -f \$(DESTDIR)/\$(DOCDIR)/{COPYING,Changelog,README,Release-Notes,TODO} rmdir --parents \$(DESTDIR)/\$(BINDIR) 2>/dev/null rmdir --parents \$(DESTDIR)/\$(MANDIR)/man1 2>/dev/null rmdir --parents \$(DESTDIR)/\$(MANDIR)/de/man1 2>/dev/null rmdir --parents \$(DESTDIR)/\$(DOCDIR) 2>/dev/null " > Makefile echo "Next thing type \"make\" and then \"make install\"" vobcopy-1.2.0/Changelog0000644000175000017500000002250011213267511014035 0ustar robosrobosChangelog for vobcopy: For more infos on the options see "man vobcopy" 1.2.0: Some new features! -Progress bar and speed enhancements/system load reduction coming with it - many thanks to Eric Kilfoil! -Vobcopy can now "rip" from an iso image on hdd or a directory containing a VIDEO_TS directory. People seem to need this for streaming dvd content to a ps3 via fuppes. That part seem to be buggy though, works 50/50. Will look further into that. -Option -M to rip the title with the longest playing time. -Other small corrections I think. 1.1.2: German l12n in the program added [x]overwrite all option small fixes, e.g. for *bsd 1.1.1: Apply patch by Petr Salinger for GNU/kFreeBSD 1.1.0: Fixes debian bug #448319/CVE-2007-5718 MacOSX (at least 10.5) compiles again other small fixes 1.0.2: I fixed a segfault in the log file writing routine. Otherwise small fixes and experimental "step over the bad part" code. 1.0.1: I may have gcc-3.4, not the whole world :) Fix in Makefile. choose the right dvd device from fstab (Jens Seidel) read only as many blocks as there are actually left (Ingo Saitz) partial fix for detection of full nfs files (Robert Story) 1.0.0: Yay! 1.0.0! Only some minor cleanup and some minor bugfixes. Still not perfect but good enough to enter "maintainance mode". vobcopy2 is being worked on! 0.9.0-pre1: Lordy told me that checking return values from library calls is a good idea - and I have to confirm :) the configure.sh script now also looks if this is an ia64/AMD64 system and use the lib64 libraries then - thanks to Steven A. Falco -D_FORTIFY_SOURCE=2 is strange, 3 bytes won't fit into a char[4] then. Well, they fit into char[8]... Some people wrote in with this, gonna name Peter Czanik because he had the fix :) Fergal Daly taught me about the finer parts of sprintf, I took some of his advice... fixed double space detection on MacOSX, hopefully... thanks Bob Maguire 0.5.16: added some code to make -n and -m mutually exclusive the size-checking code with -m was br0ken. Fixed hopefully typo in the man-page 0.5.15: with -m, if files exist you now have the option to [s]kip the files already present - by patch from Guy Naor some dvd's show files ending in ";?", they should now work. 0.5.14: some more cleanup. Another small fix for different freebsd versions. Nothing major. 0.5.14-rc1: lots of bug fixes for *bds, solaris and -tada- OSX! Quite some stuff should now work better on freebsd, openbsd and solaris since Takeshi Nakamura provided some patches. Also incorporated the fix the netbsd folks did when they incorporated 0.5.13 into their ports collection. AND it seems that OSX now works (besides fink, which provided vobcopy for quite some time already). What is needed is dlcompat IIRC. Thanks to all for their help! 0.5.14-test1: changed dvd name getting function to what Jim Hatfield found works for freebsd Davide has a dvd which has names like this: VTS_01_2.VOB;? A new routine tries to remove the ;?. On OSX, getopt.h doesn't get found. /usr/include/getopt.h should do it 0.5.13: start for copying routine adjusted to the culmulative size of the previous files (via stat). Patch from Andrew Leiserson did fix the same. patch from Mark Prusinowski: "This fails to work in my case as I don't have the mount point listed under /etc/fstab. I manually mount the drive. I created a patch that uses libc's getmntent() to retrieve the desired information directly from /etc/mtab" 0.5.12: good old off-by-one error in the -m function fixed 0.5.11: -O vts_01_4 -o - didn't write to stdout but rather to the files. Fixed. Also did info texts of vobcopy end up in stdout streams. Now all go to stderr. New option: -q (quiet): all info- and error-texts of vobcopy end up in /tmp/vobcopy.bla thanks to Dimitrios Apostolou 0.5.10: e.g -O vts_01_4 now actually copies 4, not 1 like it did before thanks Stewart Andreason some other cleanup 0.5.9: -F now needs speed factor in range 1 .. 64 and this is enforced.. new spec file (again?) - Florin Andrei 0.5.9-pre2: code cleanup and small bugfix - suggested by Ashley Martens 0.5.9-pre1: -O has now globbing function and separation of files has to be "," rename instead of link/unlink on e.g. smb 0.5.8: added -O option ("one" file copying) some fixes for solaris some support for darwin, i.e. MacOSX Added code to name the files .partial at first and rename if size is ok [Error] and [Hint] cleanup stupid error fixed for mandrakes supermount (there is no iso9660 or udf in the mount command...) 0.5.7: 32 spaces as name if no name is present on dvd is fixed fast switch (-F) added d_name[k] wasn't zero terminated, sometimes leading to garbled names. 0.5.6: fixed parsing of fstab and mtab on supermount using systems like Mandrake 0.5.5: Erik Hovland made some extensive patches to get vobcopy to work on solaris. Yeeha, another platform. Thanks a lot Erik! -bugfix: -f didn't work right 0.5.4: HIYAMA Takeshi did it again, patches for FreeBSD: dvd device detection should now work if I gather it correctly output of the log file should now work too 0.5.3: -t can now be provided for -m too to change the name of the output dir large-file support for FreeBSD (other *bsd?) added getopt-long fix for FreeBSD All these done by HIYAMA Takeshi 0.5.2: -major bug in mirror code removed (see Release-Notes) -added stuff for debian packaging -v -v fixed -now stops cleanly even if forced and no space left 0.5.1: -removed forgotten debug code -console doesn't get spammed anylonger with -m -m outputs now to DVD_NAME/VIDEO_TS/VTS... (except DVD_NAME now all uppercase since that is necessary to be able to burn it to dvd) -percent output to -m added -progression bar output now in MB rather than blocks for normal copy -removed lots of compiler warning (-Wall -pedantic) 0.5.0: OK, some steps closer to what I want to have: There is now the -m (--mirror) option which mirrors the dvd/video_ts/ content to a dir created with the name of the dvd. The vobs are decrypted though. Also long-options have been added (--Info), look in the man-page. Some cleanup and bug-fix too. 0.4.3: -HIYAMA Takeshi ported my baby to FreeBSD (I sure hope it works there ;-) 0.4.2: -small bugfix for systems using devfs. -new option -t name: You can specify the name of the output file if you don't like the one from dvd or, if you want to pipe the output someplace, say "-t stdout". 0.4.1: -small bugfix: there is a include at the beginning of 0.4.0 that`s not met by a standard install of libdvdread. -more options: -b size[bkmg] begins to copy from the specified offset-size. Modifiers like b for 512-bytes, k for kilo-bytes, m for mega- and g for giga-bytes can be appended to the number. Example: vobcopy -b 500m will start to copy from 500MB onward till the end. -e size[bkmg] similar to -b, this options lets you specify some size to stop before the end. -vobcopy takes the title with the most chapters by default if no title is specified 0.4.0: behind -1, -2, -3 and -4 you can specify auxiliary/alternative directories (but you have to take -o first) where the data will be written to. The data will be split to fit on the first (-o) and continued on the second (-1) ... (beware: the path probably has to be specified *directly* behind the number like this -1/tmp/ and might even then be necessary to to this to -o too) I gives you information about the titles, chapters and angles on the dvd. Code-specific: Moved some things into separate functions to clean up the code a little bit. 0.3.0: vobcopy has now the ability to work on it's own, meaning you can call it simply by "vobcopy" and it will find the mounted dvd and copy the first title to the directory you called vobcopy from. Alternatively some command line options emerged: -l for large file support (i.e. file output to larger than 2 GB) -i /path/to/the/mounted/dvd/ (if vobcopy doesn't do it correctly) -v being a little bit more verbose -v -v writing a log-file for bugreports to /tmp/ -h prints help for all the options -f force vobcopy to write to a directory even if it thinks there isn't enough space left -V prints the version number There have even been some efforts to get it to work under solaris, how far this actually works is unknown. Give it a try. 0.2.0: Included the -o option to specify the destination directory. The title- number has to be given now behind -n 0.1.1: Added the Makefile and alternative_programs.txt 0.1.0: Now the program checks in advance if on the destination drive (the directory from which you call vobcopy) is enough free space. It then gives you something like a progression indicator and at the very end it compares the size of what has been copied against the combined size of the title-vobs on dvd. 0.0.4: copies the decrypted vobs in 2 GB chunks to harddisk into files named after what could be extracted from the dvd (the dvd-title). File names are something like: wow-a-movie1_1.vob, wow-a-movie1_2.vob and so forth 0.0.2 - 0.0.3: dunno what happened there, don't remember 0.0.1: against all expectations on my side (I'm a lousy newbie programmer) this thing actually works! Thanx libdvdread guys. vobcopy-1.2.0/Makefile0000664000175000017500000000427411213267511013675 0ustar robosrobos #This is the makefile for vobcopy, mainly written by rosenauer. These things #below here are variable definitions. They get substituted in the (CC) and #stuff places. DESTDIR = CC ?= gcc #PREFIX += /usr/local #BINDIR = ${PREFIX}/bin #MANDIR = ${PREFIX}/man PREFIX += /usr/local BINDIR = ${PREFIX}/bin MANDIR = ${PREFIX}/man DOCDIR = ${PREFIX}/share/doc/vobcopy LFS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE CFLAGS += -I/usr/local//include LDFLAGS += -ldvdread -L/usr/local//lib #This specifies the conversion from .c to .o .c.o: $(CC) $(LFS) $(CFLAGS) -c $< #Here is implicitly said that for vobcopy to be made *.o has to be made first #make is kinda intelligent in that aspect. vobcopy: vobcopy.o dvd.o $(CC) -o vobcopy vobcopy.o dvd.o ${LDFLAGS} disable_lfs: $(CC) $(CFLAGS) -c vobcopy.c $(CC) $(CFLAGS) -c dvd.c $(CC) -o vobcopy vobcopy.o dvd.o -ldvdread debug: $(CC) -c vobcopy.c -Wall -ggdb -pedantic $(CFLAGS) $(LFS) $(CC) -c dvd.c -Wall -ggdb -pedantic $(CFLAGS) $(LFS) $(CC) -o vobcopy vobcopy.o dvd.o -ldvdread deb: echo "this here is really really experimental..." dpkg-buildpackage -rfakeroot -us -uc -tc clean : rm -f vobcopy vobcopy.o dvd.o distclean : rm -f vobcopy.o dvd.o *~ install: # mkdir -p $(MANDIR)/man1 # cp vobcopy $(BINDIR)/vobcopy # cp vobcopy.1 $(MANDIR)/man1/vobcopy.1 install -d -m 755 $(DESTDIR)/$(BINDIR) install -d -m 755 $(DESTDIR)/$(MANDIR)/man1 install -d -m 755 $(DESTDIR)/$(MANDIR)/de/man1 install -d -m 755 $(DESTDIR)/$(DOCDIR) install -m 755 vobcopy $(DESTDIR)/$(BINDIR)/vobcopy install -m 644 vobcopy.1 $(DESTDIR)/$(MANDIR)/man1/vobcopy.1 install -m 644 vobcopy.1.de $(DESTDIR)/$(MANDIR)/de/man1/vobcopy.1 install -m 644 COPYING Changelog README Release-Notes TODO $(DESTDIR)/$(DOCDIR) uninstall: rm -f $(DESTDIR)/$(BINDIR)/vobcopy rm -f $(DESTDIR)/$(MANDIR)/man1/vobcopy.1 rm -f $(DESTDIR)/$(MANDIR)/de/man1/vobcopy.1 rm -f $(DESTDIR)/$(DOCDIR)/{COPYING,Changelog,README,Release-Notes,TODO} rmdir --parents $(DESTDIR)/$(BINDIR) 2>/dev/null rmdir --parents $(DESTDIR)/$(MANDIR)/man1 2>/dev/null rmdir --parents $(DESTDIR)/$(MANDIR)/de/man1 2>/dev/null rmdir --parents $(DESTDIR)/$(DOCDIR) 2>/dev/null vobcopy-1.2.0/README0000644000175000017500000001304011213270274013102 0ustar robosrobosHi! Well, I like mplayer (www.mplayerhq.hu) a lot! Conversion and all that. But - for a quick copy of a dvd to harddisk I didn't find the right tools under linux (back then - something similar to vobdec under win). So, I hacked together a copy program using heavily the libdvdread library (which is really great). It should also now work on FreeBSD (many thanks to Takeshi HIYAMA!!) and Solaris (also many thanks to Erik Hovland!!) and on MacOSX (either straight from this source or get it via fink - that really works) What you need in advance is libdvdread(-devel) installed. This will only copy css-unencrypted dvd's (take a GOOD look at http://freshmeat.net/projects/libdvdread). There are also rpm and deb packages available! **IMPORTANT** I receive nearly NO bugreports, so either vobcopy (and therefore I) are near-perfect (yeah, right ;-) or your problems have a real slim chance of getting fixed. Bugreporting is *really* simple, add "-v -v" to your vobcopy call to have vobcopy create a bugreport file you can mail me at robos@muon.de along with a small description of your system (OS, hardware, ...) and the problem. I did receive some questions which I answer in the FAQ. Take a look there before you mail me a bugreport. It should compile then via: (Configure: ./configure.sh is a self-written configure script. Try it. It isn't necessary but it tries to find some things. If it fails skip it :) For rpm based systems the commands should be something link this: The src.rpm should rebuild cleanly on any RPM-based distro with "rpmbuild --rebuild vobcopy-0.5.8-1.src.rpm" (or replace "rpmbuild" with "rpm" on older distributions), so it's distribution-neutral. Alternatively this will build the binary package for them automagically: rpmbuild -ta vobcopy-0.5.8.tar.gz Compile: make (if you want to disable large file support during compilation, use make disable_lfs instead) Install: as root: make install Handling: vobcopy (without _any_ options) will copy the title with the most chapters to the current directory. The vobs will be merged up to 2 gigs and then a new file will be started. So what you get is: name-of-moviex-1.vob (2 gig size) name-of-moviex-2.vob ... During copying there is a .partial appended to the filename to indicate that the files are not done yet. If for some reason the sizes don't match the one on dvd the .partial will stay to indicate that something is wrong. For more infos on the options see "man vobcopy" Newest addition: vobcopy -M will rip the title with the longest playing time. Normal mode without any options is with the most chapters. Both methods can be wrong so please try both. I will implement a message when the methods deliver different "main" titles shortly. vobcopy -x will not ask any questions if you want to overwrite pre-existing files but will simply do so. vobcopy -O e.g. -O video_ts.vob,vts_01_01.ifo,vts_01_01.vob or -O bup,ifo will copy all files containing ifo and bup in their names vobcopy -F (--fast) Speed up the copying (experimental) (in my case it went from 10:43 min to 9:40 with 1x to 10x, so not THAT much, maybe with faster drives...) vobcopy -m (or --mirror, long-options are possible now) Mirror the content of /dvd/video_ts/ to a dir named after the dvd. Optionally you can provide which vts_xx_01 (which title) should be copied via vobcopy -n 3 will copy vts_03_xx.vob to harddisk. vobcopy -o /tmp/, "-" or "stdout" will copy the output to /tmp/, or to stdout for piping to another program (like bbtools, see the vobcopy page) vobcopy -1/tmp1/ will continue to write the data to this directory if the first one (behind -o) is full. Additionally there are -2, -3 and -4 available. (watch out that there are no spaces behind the number and the dir, might not work otherwise) vobcopy -l will copy the data into only one really large file (probably larger than 2 GB). This large-file-support has to be met by your system. No autodetection yet. vobcopy -h gives you the available command options (help) If parts of vobcopy work buggy you can override some things: vobcopy -f force vobcopy to write to the destination directory even if vobcopy thinks there is not enough free space. vobcopy -i /path/to/the/mounted/dvd/ if vobcopy fails to autodetect the mounted dvd you can provide the path like that. vobcopy -I will give you some infos on the dvd data and on the output directory vobcopy -v -v will write a log-file to the current directory. You can send me this as a bugreport (along with a few words by you about the problem) vobcopy -b begins to copy from the specified offset-size. Modifiers like b for 512-bytes, k for kilo-bytes, m for mega- and g for giga-bytes can be appended to the number. Example: vobcopy -b 500m will start to copy from 500MB onward till the end. vobcopy -e size[bkmg] similar to -b, this options lets you specify some size to stop before the end. vobcopy -V prints the version number of vobcopy vobcopy -t name changes the name of the output file or writes to stdout for pipeing (deprecated, use -o instead now) vobcopy -q all info and error messages of vobcopy go to vobcopy.bla in the current directory instead of stderr. Good when you want to pipe the output of vobcopy to some other program, e.g. bbtools or mplayer. vobcopy -x overwrite all existing files without further question The options can be combined and arranged as you like. It worked for me, hope for you too. Have fun! Robos (robos@muon.de) vobcopy-1.2.0/Release-Notes0000664000175000017500000000557111213270544014627 0ustar robosrobosRelease-Notes for 1.2.0 (Mo 8. Jun 21:48:19 CEST 2009): Progress bar and speed enhancements/system load reduction coming with it - many thanks to Eric Kilfoil! Also vobcopy can now "rip" from an iso image on hdd or a directory containing a VIDEO_TS directory. People seem to need this for streaming dvd content to a ps3 via fuppes. That part seem to be buggy though, works 50/50. Will look further into that. Added another option: -M to rip the title with the longest playing time. Both methods, choosing the main title by longest playing time and most chapters, can be wrong - please try both if one fails. I will implement a message indicating that the methods recommend different "main" titles shortly. Other small corrections are also in I think. Release-Notes for 1.1.2 (Mi 8. Okt 00:18:17 CEST 2008): Added german l12n to the messages in vobcopy (if it works..., please let me know if not). Also some small fixes for *bsd and other fixes. And introduced in vobcopy to [x]overwrite all existing files or -x to start that way from the command line. Release-Notes for 1.0.2 (Su 24. Jun 02:19:04 CEST 2007): Small fixes all in all: fix segfault with log file writing routine and some other small fixes. Also a small experimental patch which steps over broken parts on a dvd (is a copy protection system). Does not work properly yet... Release-Notes for 1.0.1 (Mo Nov 13 22:56:00 CET 2006): Some small fixes. Nothing major. Not everything is up to par but I think that that bug I'm (slowly) fixing is rare enough that people won't notice and I think it's better to get it out the door, it's been lying on my hdd for ages... Release-Notes for 1.0.0 (So 2 Apr 18:49:46 CEST 2006): This is it! Vobcopy is "ready" in the sense that it can be in maintainance mode from now on. I'm working on vobcopy2 (sort of) and that will be massively re-written. So, until then, enjoy this one here! Release-Notes for 0.9.0-pre1 (Fr Feb 24 21:15:36 CET 2006): Backup Release Release-Notes for 0.5.16 (Wed Dec 7 23:32:50 CET 2005): Rather minor stuff: -m and -n are mutually exclusive -now they are also in the code. The size-checking code in the -m part was broken and is hopefully fixed now. And a typo in the man-page. Release-Notes for 0.5.15 (Fr Jul 29 04:00:01 CEST 2005): By a patch from Guy Naor there is now the option to skip already copied files (from a previous run). Strange dvd's with files ending in ";?" should now also work. Release-Notes for 0.5.14 (Thu Nov 18 06:08:53 CET 2004): There have been some small cleanups that clear up a little what is being named what and such... also another small code-path for freebsd Release-Notes for 0.5.14-rc1 (Son Okt 24 04:00:41 CEST 2004): Takeshi Nakamura provided quite some patches to get parts of vobcopy to work better with openbsd, freebsd and solaris. From him I also learned about netbsd patches from the netbsd folks I incorporated. I dunno what else, sorry, forgot... vobcopy-1.2.0/alternative_programs.txt0000644000175000017500000000114011213270546017213 0ustar robosrobosCopying of dvd to harddisk, ripping the vobs to harddisk with tools like: dvdbackup http://dvd.chevelless230.com/dvdbackup.html mplayer dvd:// -dumpstream (http://www.mplayerhq.hu) play_title (from libdvdread guys, http://linuxvideo.org/cvs/viewcvs.cgi/libdvdread/src/play_title.c) tccat from the transcode package (http://www.theorie.physik.uni-goettingen.de/~ostreich/transcode/) cpvts cpdvd lxdvdrip (all 3 not tested by me) vobcopy from www.linux-programming-newbie.org All of these tools are something similar to vobdec/DVDEcyptor under win (think so, my vobcopy at least is ;-) Robos vobcopy-1.2.0/dvd.c0000644000175000017500000005516511213270546013163 0ustar robosrobos/* This file is part of vobcopy. * * vobcopy is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * vobcopy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with vobcopy; if not, see . */ #include "vobcopy.h" #include /* included from cdtitle.c (thx nils *g) * get the Title * returns 0 on success or a value < 0 on error */ int get_dvd_name(const char *device, char *title) { #if defined( __sun ) /* title is actually in the device name */ char *new_title; new_title = strstr( device, "d0/" ) + strlen( "d0/" ); strncpy( title, new_title, sizeof(title)-1 ); #else int filehandle = 0; int i = 0, last = 0; int bytes_read; char tmp_buf[2048]; /* open the device */ if ( !(filehandle = open(device, O_RDONLY, 0)) ) { /* open failed */ fprintf( stderr, _("[Error] Something went wrong while getting the dvd name - please specify path as /cdrom or /dvd (mount point) or use -t\n")); fprintf( stderr, _("[Error] Opening of the device failed\n")); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); return -1; } /* seek to title of first track, which is at (track_no * 32768) + 40 */ if ( 32768 != lseek( filehandle, 32768, SEEK_SET ) ) { /* seek failed */ close( filehandle ); fprintf( stderr, _("[Error] Something went wrong while getting the dvd name - please specify path as /cdrom or /dvd (mount point) or use -t\n")); fprintf( stderr, _("[Error] Couldn't seek into the drive\n")); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); return -1; } /* read title */ if ( (bytes_read = read(filehandle, tmp_buf, 2048)) != 2048 ) { close(filehandle); fprintf( stderr, _("[Error] something wrong in dvd_name getting - please specify path as /cdrom or /dvd (mount point) or use -t\n") ); fprintf( stderr, _("[Error] only read %d bytes instead of 2048\n"), bytes_read); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } strncpy( title, &tmp_buf[40], 32 ); /* make sure string is terminated */ title[32] = '\0'; /* we don't need trailing spaces */ /* find the last character that is not ' ' */ last = 0; /* and checkski below if it changes*/ for ( i = 0; i < 32; i++ ) { if ( title[i] != ' ' ) { last = i; } } if( 0 == last ) { fprintf( stderr, _("[Hint] The dvd has no name, will choose a nice one ;-), else use -t\n") ); strcpy( title, "insert_name_here\0" ); } else title[ last + 1 ] = '\0'; #endif for( i=0; i< strlen(title);i++ ) { if( title[i] == ' ') title[i] = '_'; } return 0; } /* function to get the device of a given pathname */ /* returns 0 if successful and NOT mounted */ /* 1 if successful and mounted */ /* returns <0 if error */ int get_device( char *path, char *device ) { #if ( !defined( __sun ) ) FILE *tmp_streamin; char tmp_bufferin[ MAX_STRING ]; char tmp_path[ 256 ]; int l = 0; #endif #if (defined(__linux__)) struct mntent* lmount_entry; #endif #if ( defined( __sun ) ) FILE *mnttab_fp; char *mnt_special; int mntcheck; char *new_device; #endif char *pointer; char *k; bool mounted = FALSE; #ifdef USE_STATFS_FOR_DEV struct statfs buf; #endif #ifdef USE_STATVFS_FOR_DEV struct statvfs buf; #endif /* the string should have no trailing / */ if( path[ ( strlen( path ) - 1 ) ] == '/' ) { path[ ( strlen( path ) - 1 ) ] = '\0' ; } /* remove video_ts if given */ if( ( pointer = strstr( path, "/video_ts" ) ) || ( pointer = strstr( path, "/VIDEO_TS" ) ) ) { *pointer = '\0'; } /* check if it is given as /dev/xxx already */ if( strstr( path, "/dev/" ) ) { strcpy( device, path ); } else { /* *look through /etc/mtab to see if it's actually mounted */ #if ( defined( USE_STATFS_FOR_DEV ) || defined( USE_STATVFS_FOR_DEV ) ) #ifdef USE_STATFS_FOR_DEV if( !statfs( path, &buf ) ) #else if( !statvfs( path, &buf ) ) #endif { if( !strcmp( path, buf.f_mntonname ) ) { mounted = TRUE; #if defined(__FreeBSD__) && (__FreeBSD_Version > 500000) strcpy(device, buf.f_mntfromname); #else strcpy(device, "/dev/r"); strcat(device, buf.f_mntfromname + 5); #endif return mounted; } strcpy(device, buf.f_mntfromname); } else { fprintf( stderr, _("[Error] Error while reading filesystem info") ); return -1; } #elif ( defined( __sun ) ) struct mnttab mount_entry; int mntcheck; if ( ( mnttab_fp = fopen( "/etc/mnttab", "r" ) ) == NULL ) { fprintf( stderr, _(" [Error] Could not open mnttab for searching!\n") ); fprintf( stderr, _(" [Error] error: %s\n"), strerror( errno ) ); return -1; } while ( ( mntcheck = getmntent( mnttab_fp, &mount_entry ) ) == 0 ) { /* check to see if our path is this entry */ if ( strcmp( path, mount_entry.mnt_mountp ) == 0 ) { char *new_device, *mnt_special; if ( strstr( mount_entry.mnt_special, "/dsk/" ) == NULL ) { fprintf( stderr, _("[Error] %s doesn't look like a disk device to me"), mount_entry.mnt_special ); return -1; } /* we actually want the raw device name */ mnt_special = malloc( strlen( mount_entry.mnt_special ) + 1 ); new_device = malloc( strlen( mount_entry.mnt_special ) + 2 ); strcpy( mnt_special, mount_entry.mnt_special ); strcpy( new_device, mnt_special ); strcpy( strstr( new_device, "/dsk/" ), "" ); strcat( new_device, "/rdsk/" ); strcat( new_device, strstr( mnt_special, "/dsk/" ) + strlen( "/dsk/" ) ); strncpy( device, new_device, sizeof(device)-1 ); free( mnt_special ); free( new_device ); mounted = TRUE; break; } } if ( mntcheck > 0 ) { fprintf( stderr, _("[Error] Encountered error in reading mnttab file\n") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } else if ( mntcheck == -1 ) { fprintf( stderr, _("[Error] Did not find mount %s in mnttab!\n"), path ); return -1; } #else /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this is the code for the other-OSs, not solaris*/ #if (defined(__linux__)) if ((tmp_streamin = setmntent("/etc/mtab", "r"))){ while ((lmount_entry = getmntent(tmp_streamin))){ if (strcmp(lmount_entry->mnt_dir, path) == 0){ /* Found the mount point */ fprintf ( stderr, "[Info] Device %s mounted on %s\n", lmount_entry->mnt_fsname, lmount_entry->mnt_dir); strcpy(device, lmount_entry->mnt_fsname); mounted = TRUE; break; } } endmntent(tmp_streamin); if (mounted) { /* device was set from /etc/mtab, no need to further check * /etc/fstab */ return mounted; } } #endif if( ( tmp_streamin = fopen( "/etc/mtab", "r" ) ) ) { strcpy( tmp_path, path ); strcat( tmp_path, " " ); /* otherwise it would detect that e.g. /cdrom is mounted even if only/cdrom1 is mounted */ memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin )) { if( strstr( tmp_bufferin, tmp_path ) ) { mounted = TRUE; } } fclose( tmp_streamin ); } else { fprintf( stderr, _("[Error] Could not read /etc/mtab!\n") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } #endif #if defined( __sun ) } #else /* *read the device out of /etc/fstab */ if( ( tmp_streamin = fopen( "/etc/fstab", "r" ) ) ) { strcpy(tmp_path, path); memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin ) ) { if( ( pointer = strstr( tmp_bufferin, tmp_path ) ) ) { if( isgraph( ( int ) *( pointer + strlen( tmp_path ) ) ) ) break; /* there is something behind the path name, for instance like it would find /cdrom but also /cdrom1 since /cdrom is a subset of /cdrom1 */ /*isblank should work too but how do you do that with the "gnu extension"? (man isblank) */ if( ( k = strstr( tmp_bufferin, "/dev/" ) ) == NULL ) { fprintf( stderr, _("[Error] Weird, no /dev/ entry found in the line where iso9660 or udf gets mentioned in /etc/fstab\n") ); return -1; } l=0; while( isgraph( (int) *(k) ) ) { device[l] = *(k); if( device[l] == ',' ) break; l++; k++; } if( isdigit( ( int) device[l-1] ) ) { if( strstr( device, "hd" ) ) fprintf( stderr, _("[Hint] Hmm, the last char in the device path (%s) that gets mounted to %s is a number.\n"), device, path); } device[l] = '\0'; } memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); } fclose( tmp_streamin ); if( !strstr( device, "/dev" ) ) { fprintf( stderr, _("[Error] Could not find the provided path (%s), typo?\n"),path); device[0] = '\0'; return -1; } } else { fprintf( stderr, _("[Error] Could not read /etc/fstab!") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); device[0] = '\0'; return -1; } } #endif return mounted; } /* function to get the device WITHOUT a given pathname */ /* therefore called oyo - on your own */ /* returns 0 if successful and NOT mounted */ /* 1 if successful and mounted */ /* returns <0 if error */ int get_device_on_your_own( char *path, char *device ) { /*oyo*/ #ifdef USE_GETMNTINFO int i, n, dvd_count = 0; #ifdef GETMNTINFO_USES_STATFS struct statfs *mntbuf; #else struct statvfs *mntbuf; #endif if( ( n = getmntinfo( &mntbuf, 0 ) ) > 0 ) { for( i = 0; i < n; i++ ) { if( strstr( mntbuf[i].f_fstypename, "cd9660" ) || strstr( mntbuf[i].f_fstypename, "udf" ) ) { dvd_count++; strcpy( path, mntbuf[i].f_mntonname ); #if defined(__FreeBSD__) && (__FreeBSD_Version > 500000) strcat(device, mntbuf[i].f_mntfromname); #else strcpy(device, "/dev/r"); strcat(device, mntbuf[i].f_mntfromname + 5); #endif } } if(dvd_count == 0) { /* no cd found? Then user should mount it */ fprintf( stderr, _("[Error] There seems to be no cd/dvd mounted. Please do that..\n")); return -1; } } else { fprintf( stderr, _("[Error] An error occured while getting mounted file system information\n")); return -1; } #elif ( defined( __sun ) ) /* Completely rewritten search of a mounted DVD on Solaris, much cleaner. No more parsing of strings -- lb */ /* the mnttab file */ FILE *mnttab_fp; /* The mount entry found */ struct mnttab mountEntry; /* The mount search fields */ struct mnttab udfsMount; /* Number of found entries */ int dvd_count = 0; /* Result of the mount search */ int result = 0; /* We're looking for any udfs-mounted FS Note that this is not always a DVD */ udfsMount.mnt_mountp = NULL; udfsMount.mnt_special = NULL; udfsMount.mnt_fstype = "udfs"; udfsMount.mnt_mntopts = NULL; udfsMount.mnt_time = NULL; /* Try to open the mnttab info */ if (( mnttab_fp = fopen( "/etc/mnttab", "r" ) ) == NULL) { fprintf( stderr, _("[Error] Could not open mnttab for searching!\n") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } /* Get the matching mount points */ /* If there is a match, handle it */ while ((result = getmntany(mnttab_fp, &mountEntry, &udfsMount)) == 0) { dvd_count++; } /* If the last result is not -1, there was a problem -- exit */ if (result != -1) return -1; /* no cd found? Then user should mount it */ if (dvd_count == 0) { fprintf( stderr, _("[Error] There seems to be no cd/dvd mounted. Please do that..\n")); return -1; } /* Copy the device name and mount points to the output variables */ strcpy(path, mountEntry.mnt_mountp); strcpy(device, mountEntry.mnt_special); #else /* End ifdef(__sun) */ FILE *tmp_streamin; char tmp_bufferin[MAX_STRING]; /* char tmp_path[20]; */ int l = 0, dvd_count = 0; char *k; /* *read the device out of /etc/mtab */ if( ( tmp_streamin = fopen( "/etc/mtab", "r" ) ) ) { /* strcpy(tmp_path, "iso9660"); */ memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin ) ) { /* if(strstr( tmp_bufferin, tmp_path)) */ if (strstr( tmp_bufferin, "iso9660" ) || strstr( tmp_bufferin, "udf" ) || strstr( tmp_bufferin, "cdrom" ) || strstr( tmp_bufferin, "dvd" ) ) { dvd_count++; /*count every cd we find */ /* extract the device */ if( ( k = strstr( tmp_bufferin, "/dev/" ) ) == NULL ) { fprintf( stderr, _("[Error] Weird, no /dev/ entry found in the line where iso9660, udf or cdrom gets mentioned in /etc/mtab\n") ); dvd_count--; continue; } while(isgraph( (int) *(k) )) { device[l] = *(k); if( device[l] == ',' ) break; l++; k++; } device[l] = '\0'; if(isdigit((int)device[l-1])) { if( strstr( device, "hd" ) ) fprintf( stderr, _("[Hint] Hmm, the last char in the device path %s is a number.\n"), device ); } /*The syntax of /etc/fstab and mtab seems to be something like this: Either /dev/hdc /cdrom or, in case of supermount none /mnt/cdrom supermount ro,dev=/dev/hdc, Therefore I parse for /dev/ first and take everything up to a blank for the device and then I locate the first space in this line and after that comes the mount-point */ k = strstr( tmp_bufferin, " " ); /*traverse the gap*/ if( isgraph( (int) *(k) )) k++; while(!(isgraph( (int) *(k) ))) k++; /* extract the path the device has been mounted to */ l=0; while(isgraph( (int) *(k) )) { if (!strncmp(k, "\\040", 4)) { /* replace escaped ASCII space ... */ path[l++] = ' '; /* ... with literal space */ k+=4; } else { path[l] = *(k); k++; l++; } } path[l] = '\0'; } memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); l = 0; /*for the next run we take the last entry in /etc/mtab since that has been mounted the last and we assume that this is the dvd. */ } fclose( tmp_streamin ); if(dvd_count == 0) { /* no cd found? Then user should mount it */ fprintf( stderr, _("[Error] There seems to be no cd/dvd mounted. Please do that..\n")); return -1; } } else { fprintf( stderr, _("[Error] Could not read /etc/mtab!")); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } #endif return dvd_count; } /******************* get the whole vob size via stat() ******************/ off_t get_vob_size( int title, char *provided_input_dir ) { char path_to_vobs[278], path_to_vobs1[278], path_to_vobs2[278], path_to_vobs3[278]; char stat_path[278]; int subvob; FILE *tmp_streamin1; struct stat buf; off_t vob_size = 0; /* first option: path/vts_xx_yy.vob */ sprintf( path_to_vobs, "%s/vts_%.2d", provided_input_dir, title ); /*which title-vob */ /* second option: path/VTS_XX_YY.VOB */ sprintf( path_to_vobs1, "%s/VTS_%.2d", provided_input_dir, title ); /*which title-vob */ /* third option: path/VIDEO_TS/VTS_XX_YY.VOB */ sprintf( path_to_vobs2, "%s/VIDEO_TS/VTS_%.2d", provided_input_dir, title ); /*which title-vob */ /* fourth option: path/video_ts/vts_xx_yy.vob */ sprintf( path_to_vobs3, "%s/video_ts/vts_%.2d", provided_input_dir, title ); /*which title-vob */ /* * extract the size of the files on dvd using stat */ sprintf( stat_path, "%s_1.vob", path_to_vobs ); if( ( tmp_streamin1 = fopen( stat_path, "r" ) ) != NULL ) /*check if this path is correct*/ { fclose ( tmp_streamin1 ); subvob = 1; while( !stat( stat_path, &buf ) ) { /* adjust path for next subvob */ subvob++; sprintf( stat_path, "%s_%d.vob", path_to_vobs, subvob ); vob_size += buf.st_size; } return ( off_t ) vob_size; } sprintf( stat_path, "%s_1.VOB", path_to_vobs1 ); if( ( tmp_streamin1 = fopen( stat_path, "r" ) ) != NULL ) /*check if this path is correct */ { fclose ( tmp_streamin1 ); subvob = 1; while( !stat( stat_path, &buf ) ) { /* adjust path for next subvob */ subvob++; sprintf( stat_path, "%s_%d.VOB", path_to_vobs1, subvob ); vob_size += buf.st_size; } return ( off_t ) vob_size; } sprintf( stat_path, "%s_1.VOB", path_to_vobs2 ); if( ( tmp_streamin1 = fopen( stat_path, "r" ) ) != NULL ) /*check if this path is correct */ { fclose ( tmp_streamin1 ); subvob = 1; while( !stat( stat_path, &buf ) ) { /* adjust path for next subvob */ subvob++; sprintf( stat_path, "%s_%d.VOB", path_to_vobs2, subvob ); vob_size += buf.st_size; } return ( off_t ) vob_size; } sprintf( stat_path, "%s_1.vob", path_to_vobs3 ); if( ( tmp_streamin1 = fopen( stat_path, "r" ) ) != NULL ) /*check if this path is correct */ { fclose ( tmp_streamin1 ); subvob = 1; while( !stat( stat_path, &buf ) ) { /* adjust path for next subvob */ subvob++; sprintf( stat_path, "%s_%d.vob", path_to_vobs3, subvob ); vob_size += buf.st_size; } return ( off_t ) vob_size; } /*none of the above seemed to have caught it, so this is the error return */ return ( off_t ) 0; /* think that (off_t) is not really needed here? as it is defined as off_t and the function is also defined as off_t */ } /*dvdtime2msec, converttime and get_longest_title are copy-paste'd from lsdvd*/ int dvdtime2msec(dvd_time_t *dt) { double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97}; double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6]; long ms; ms = (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600000; ms += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000; ms += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000; if(fps > 0) ms += ((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f) * 1000.0 / fps; return ms; } void converttime(playback_time_t *pt, dvd_time_t *dt) { double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97}; double fps = frames_per_s[(dt->frame_u & 0xc0) >> 6]; pt->usec = pt->usec + ((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f) * 1000.0 / fps; pt->second = pt->second + ((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f); pt->minute = pt->minute + ((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f); pt->hour = pt->hour + ((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f); if ( pt->usec >= 1000 ) { pt->usec -= 1000; pt->second++; } if ( pt->second >= 60 ) { pt->second -= 60; pt->minute++; } if ( pt->minute > 59 ) { pt->minute -= 60; pt->hour++; } } int get_longest_title( dvd_reader_t *dvd ) { /* dvd_reader_t *dvd; */ ifo_handle_t *ifo_zero, **ifo; pgcit_t *vts_pgcit; vtsi_mat_t *vtsi_mat; vmgi_mat_t *vmgi_mat; video_attr_t *video_attr; pgc_t *pgc; int i, j, titles, vts_ttn, title_set_nr; int max_length = 0, max_track = 0; struct dvd_info dvd_info; ifo_zero = ifoOpen(dvd, 0); if ( !ifo_zero ) { fprintf( stderr, "Can't open main ifo!\n"); return 3; } ifo = (ifo_handle_t **)malloc((ifo_zero->vts_atrt->nr_of_vtss + 1) * sizeof(ifo_handle_t *)); for (i=1; i <= ifo_zero->vts_atrt->nr_of_vtss; i++) { ifo[i] = ifoOpen(dvd, i); if ( !ifo[i] ) { fprintf( stderr, "Can't open ifo %d!\n", i); return 4; } } titles = ifo_zero->tt_srpt->nr_of_srpts; vmgi_mat = ifo_zero->vmgi_mat; /* dvd_info.discinfo.device = dvd_device; */ /* dvd_info.discinfo.disc_title = has_title ? "unknown" : title; */ dvd_info.discinfo.vmg_id = vmgi_mat->vmg_identifier; dvd_info.discinfo.provider_id = vmgi_mat->provider_identifier; dvd_info.title_count = titles; dvd_info.titles = calloc(titles, sizeof(*dvd_info.titles)); for (j=0; j < titles; j++) { /* GENERAL */ if (ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat) { vtsi_mat = ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vtsi_mat; vts_pgcit = ifo[ifo_zero->tt_srpt->title[j].title_set_nr]->vts_pgcit; video_attr = &vtsi_mat->vts_video_attr; vts_ttn = ifo_zero->tt_srpt->title[j].vts_ttn; vmgi_mat = ifo_zero->vmgi_mat; title_set_nr = ifo_zero->tt_srpt->title[j].title_set_nr; pgc = vts_pgcit->pgci_srp[ifo[title_set_nr]->vts_ptt_srpt->title[vts_ttn - 1].ptt[0].pgcn - 1].pgc; dvd_info.titles[j].general.length = dvdtime2msec(&pgc->playback_time)/1000.0; converttime(&dvd_info.titles[j].general.playback_time, &pgc->playback_time); dvd_info.titles[j].general.vts_id = vtsi_mat->vts_identifier; if (dvdtime2msec(&pgc->playback_time) > max_length) { max_length = dvdtime2msec(&pgc->playback_time); max_track = j+1; } } } return max_track; } vobcopy-1.2.0/dvd.h0000644000175000017500000000303511213270546013155 0ustar robosrobos/*this files is part of vobcopy*/ int get_dvd_name(const char *, char *); int get_device(char *, char *); int get_device_on_your_own(char *, char *); off_t get_vob_size(int , char *); /* int dvdtime2msec(dvd_time_t *); */ /* void converttime(playback_time_t *, dvd_time_t *); */ int get_longest_title( dvd_reader_t * ); typedef struct { int hour; int minute; int second; int usec; } playback_time_t; struct dvd_info { struct { char *device; char *disc_title; char *vmg_id; char *provider_id; } discinfo; int title_count; struct { int enabled; struct { float length; playback_time_t playback_time; char *vts_id; } general; struct { int vts; int ttn; float fps; char *format; char *aspect; char *width; char *height; char *df; } parameter; int angle_count; /* no real angle detail is available... but hey. */ int audiostream_count; struct { char *langcode; char *language; char *format; char *frequency; char *quantization; int channels; int ap_mode; char *content; int streamid; } *audiostreams; int chapter_count_reported; /* This value is sometimes wrong */ int chapter_count; /* This value is real */ struct { float length; playback_time_t playback_time; int startcell; } *chapters; int cell_count; struct { float length; playback_time_t playback_time; } *cells; int subtitle_count; struct { char *langcode; char *language; char *content; int streamid; } *subtitles; int *palette; } *titles; int longest_track; }; vobcopy-1.2.0/vobcopy.c0000644000175000017500000024550711213270546014070 0ustar robosrobos/* vobcopy 1.2.0 * * Copyright (c) 2001 - 2009 robos@muon.de * Lots of contribution and cleanup from rosenauer@users.sourceforge.net * Critical bug-fix from Bas van den Heuvel * Takeshi HIYAMA made lots of changes to get it to run on FreeBSD * Erik Hovland made changes for solaris * This file is part of vobcopy. * * vobcopy is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * vobcopy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with vobcopy; if not, see . */ /* CONTRIBUTORS (direct or through source "borrowing") * rosenauer@users.sf.net - helped me a lot! * Billy Biggs - took some of his play_title.c code * and implemeted it here * Håkan Hjort and Billy Biggs - libdvdread * Stephen Birch - debian packaging */ /*TODO: * mnttab reading is "wrong" on solaris * - error handling with the errno and strerror function * with -t still numbers get added to the name, -T with no numbers or so. */ /*THOUGHT-ABOUT FEATURES * - being able to specify - which title - which chapter - which angle - which language(s) - which subtitle(s) to copy * - print the total playing time of that title */ /*If you find a bug, contact me at robos@muon.de*/ #include "vobcopy.h" extern int errno; char name[300]; bool overwrite_flag = FALSE; bool overwrite_all_flag = FALSE; int overall_skipped_blocks = 0; /* --------------------------------------------------------------------------*/ /* MAIN */ /* --------------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) { int streamout, block_count, blocks, file_block_count; int op; char dvd_path[255], logfile_name[20],logfile_path[280]="\0"; /* TODO: fill logfile_path with all zeros so that " if strncpy() finds the source too long IT DOES NOT TERMINATE the sink, so the following strcat() is undefined and potentially fatal." - Thanks Leigh!*/ char dvd_name[35], vobcopy_call[255], provided_dvd_name[35]; char *size_suffix; char pwd[255],provided_output_dir[255],provided_input_dir[255]; char alternate_output_dir[4][255], onefile[255]; unsigned char bufferin[ DVD_VIDEO_LB_LEN * BLOCK_COUNT ]; int i = 0,j = 0, argc_i = 0, alternate_dir_count = 0; int partcount = 0, get_dvd_name_return, options_char = 0; int dvd_count = 0, verbosity_level = 0, paths_taken = 0, fast_factor = 1; int watchdog_minutes = 0; long long unsigned int seek_start = 0, stop_before_end = 0, temp_var; off_t pwd_free, vob_size = 0, disk_vob_size = 0; off_t offset = 0, free_space = 0; off_t max_filesize_in_blocks = 1048571; /* for 2^31 / 2048 */ off_t max_filesize_in_blocks_summed = 0, angle_blocks_skipped = 0; ssize_t file_size_in_blocks = 0; bool mounted = FALSE, provided_output_dir_flag = FALSE; bool verbose_flag = FALSE, provided_input_dir_flag = FALSE; bool force_flag = FALSE, info_flag = FALSE, cut_flag = FALSE; bool large_file_flag = FALSE, titleid_flag = FALSE; bool mirror_flag = FALSE, provided_dvd_name_flag = FALSE; bool stdout_flag = FALSE, space_greater_2gb_flag = TRUE; bool fast_switch = FALSE, onefile_flag = FALSE; bool quiet_flag = FALSE, longest_title_flag = FALSE; struct stat buf; float lastpos = 0; int starttime; dvd_reader_t *dvd = NULL; dvd_file_t *dvd_file = NULL; extern char *optarg; extern int optind, optopt; /** *this is taken from play_title.c */ int titleid = 2, chapid = 0, pgc_id, start_cell; int angle = 0, ttn, pgn, sum_chapters = 0; int sum_angles = 0, most_chapters = 0; ifo_handle_t *vmg_file; tt_srpt_t *tt_srpt; ifo_handle_t *vts_file; vts_ptt_srpt_t *vts_ptt_srpt; pgc_t *cur_pgc; /* this is for the mirror feature (readdir) */ struct dirent * directory; DIR *dir; /** *getopt-long */ #ifdef HAVE_GETOPT_LONG int option_index = 0; static struct option long_options[] = { {"1st_alt_output_dir", 1, 0, '1' }, {"2st_alt_output_dir", 1, 0, '2'}, {"3st_alt_output_dir", 1, 0, '3'}, {"4st_alt_output_dir", 1, 0, '4'}, {"angle", 1, 0, 'a'}, {"begin", 1, 0, 'b'}, {"chapter", 1, 0, 'c'}, {"end", 1, 0, 'e'}, {"force", 0, 0, 'f'}, {"fast", 1, 0, 'F'}, {"help", 0, 0, 'h'}, {"input-dir", 1, 0, 'i'}, {"info", 0, 0, 'I'}, {"large-file", 0, 0, 'l'}, {"longest", 0, 0, 'M'}, {"mirror", 0, 0, 'm'}, {"title-number", 1, 0, 'n'}, {"output-dir", 1, 0, 'o'}, {"quiet", 0, 0, 'q'}, {"onefile", 1, 0, 'O'}, {"name", 1, 0, 't'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, 'V'}, {"watchdog", 1, 0, 'w'}, {"overwrite-all", 0, 0, 'x'}, {0, 0, 0, 0} }; #endif /*for gettext - i18n */ #if defined( __gettext__ ) setlocale(LC_ALL, ""); textdomain("vobcopy"); bindtextdomain("vobcopy", "/usr/share/locale"); #endif /* initialize string */ dvd_path[0] = '\0'; /* * the getopt part (getting the options from command line) */ while (1) { #ifdef HAVE_GETOPT_LONG options_char = getopt_long( argc, argv, "1:2:3:4:a:b:c:e:i:n:o:qO:t:vfF:lmMhL:Vw:Ix", long_options ,&option_index); #else options_char = getopt( argc, argv, "1:2:3:4:a:b:c:e:i:n:o:qO:t:vfF:lmMhL:Vw:Ix-" ); #endif if ( options_char == -1 ) break; switch( options_char ) { case'a': /*angle*/ if ( !isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] The thing behind -a has to be a number! \n") ); exit(1); } sscanf( optarg, "%i", &angle ); angle--;/*in the ifo they start at zero */ if (angle < 0) { fprintf( stderr, _("[Hint] Um, you set angle to 0, try 1 instead ;-)\n") ); exit(1); } break; case'b': /*size to skip from the beginning (beginning-offset) */ if ( !isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] The thing behind -b has to be a number! \n") ); exit(1); } temp_var = atol( optarg ); size_suffix = strpbrk( optarg, "bkmgBKMG" ); if( !size_suffix) { fprintf( stderr, _("[Error] Wrong suffix behind -b, only b,k,m or g \n") ); exit(1); } switch( *size_suffix ) { case'b': case'B': temp_var *= 512;/*blocks (normal, not dvd)*/ break; case'k': case'K': temp_var *= 1024; /*kilo*/ break; case'm': case'M': temp_var *= ( 1024 * 1024 );/*mega*/ break; case'g': case'G': temp_var *= ( 1024 * 1024 * 1024 );/*wow, giga *g */ break; case'?': fprintf( stderr, _("[Error] Wrong suffix behind -b, only b,k,m or g \n") ); exit(1); break; } /* sscanf( optarg, "%lli", &temp_var ); */ seek_start = abs( temp_var / 2048 ); if( seek_start < 0 ) seek_start = 0; cut_flag = TRUE; break; case'c': /*chapter*/ /*NOT WORKING!!*/ if ( !isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] The thing behind -c has to be a number! \n") ); exit(1); } sscanf( optarg, "%i", &chapid ); chapid--;/*in the ifo they start at zero */ break; case'e': /*size to stop from the end (end-offset) */ if ( !isdigit( (int) optarg[0] ) ) { fprintf( stderr, _("[Error] The thing behind -e has to be a number! \n") ); exit(1); } temp_var = atol( optarg ); size_suffix = strpbrk( optarg, "bkmgBKMG" ); if( !size_suffix) { fprintf( stderr, _("[Error] Wrong suffix behind -b, only b,k,m or g \n") ); exit(1); } switch( *size_suffix ) { case'b': case'B': temp_var *= 512; /*blocks (normal, not dvd)*/ break; case'k': case'K': temp_var *= 1024; /*kilo*/ break; case'm': case'M': temp_var *= ( 1024 * 1024 ); /*mega*/ break; case'g': case'G': temp_var *= ( 1024 * 1024 * 1024 );/*wow, giga *g */ break; case'?': fprintf( stderr, _("[Error] Wrong suffix behind -b, only b,k,m or g \n") ); exit(1); break; } stop_before_end = abs( temp_var / 2048 ); if( stop_before_end < 0 ) stop_before_end = 0; cut_flag = TRUE; break; case'f': /*force flag, some options like -o, -1..-4 set this themselves */ force_flag = TRUE; break; case'h': /* good 'ol help */ usage( argv[0] ); break; case'i': /*input dir, if the automatic needs to be overridden */ if ( isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] Erm, the number comes behind -n ... \n") ); exit(1); } fprintf( stderr, _("[Hint] You use -i. Normally this is not necessary, vobcopy finds the input dir by itself. This option is only there if vobcopy makes trouble.\n") ); fprintf( stderr, _("[Hint] If vobcopy makes trouble, please mail me so that I can fix this (robos@muon.de). Thanks\n") ); safestrncpy( provided_input_dir, optarg, sizeof(provided_input_dir)-1 ); if( strstr( provided_input_dir, "/dev" ) ) { fprintf( stderr, _("[Error] Please don't use -i /dev/something in this version, only the next version will support this again.\n") ); fprintf( stderr, _("[Hint] Please use the mount point instead (/cdrom, /dvd, /mnt/dvd or something)\n") ); } provided_input_dir_flag = TRUE; break; #if defined( HAS_LARGEFILE ) || defined( MAC_LARGEFILE ) case'l': /*large file output*/ max_filesize_in_blocks = 8388608; /*16 GB /2048 (block) */ /* 2^63 / 2048 (not exactly) */ large_file_flag = TRUE; break; #endif case'm':/*mirrors the dvd to harddrive completly*/ mirror_flag = TRUE; info_flag = TRUE; break; case'M':/*Main track - i.e. the longest track on the dvd*/ titleid_flag = TRUE; longest_title_flag = TRUE; break; case'n': /*title number*/ if ( !isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] The thing behind -n has to be a number! \n") ); exit(1); } sscanf( optarg, "%i", &titleid ); titleid_flag = TRUE; break; case'o': /*output destination */ if ( isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Hint] Erm, the number comes behind -n ... \n") ); } safestrncpy( provided_output_dir, optarg, sizeof(provided_output_dir)-1 ); if ( !strcasecmp( provided_output_dir, "stdout" ) || !strcasecmp( provided_output_dir, "-" ) ) { stdout_flag = TRUE; force_flag = TRUE; } else { provided_output_dir_flag = TRUE; alternate_dir_count++; } /* force_flag = TRUE; */ break; case'q':/*quiet flag* - meaning no progress and such output*/ quiet_flag = TRUE; break; case'1': /*alternate output destination*/ case'2': case'3': case'4': if( alternate_dir_count < options_char - 48 ) { fprintf( stderr, _("[Error] Please specify output dirs in this order: -o -1 -2 -3 -4 \n") ); exit( 1 ); } if ( isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Hint] Erm, the number comes behind -n ... \n") ); } safestrncpy( alternate_output_dir[ options_char-49 ], optarg, sizeof(alternate_output_dir[ options_char-49 ])-1 ); provided_output_dir_flag = TRUE; alternate_dir_count++; force_flag = TRUE; break; case't': /*provided title instead of the one from dvd, maybe even stdout output */ if ( strlen( optarg ) > 33 ) printf( "[Hint] The max title-name length is 33, the remainder got discarded" ); safestrncpy( provided_dvd_name, optarg, sizeof(provided_dvd_name)-1 ); provided_dvd_name_flag = TRUE; if ( !strcasecmp( provided_dvd_name,"stdout" ) || !strcasecmp( provided_dvd_name,"-" ) ) { stdout_flag = TRUE; force_flag = TRUE; } for( i=0; i< strlen(provided_dvd_name);i++ ) { if( provided_dvd_name[i] == ' ') provided_dvd_name[i] = '_'; } break; case'v': /*verbosity level, can be called multiple times*/ verbose_flag = TRUE; verbosity_level++; break; case'w': /*sets a watchdog timer to cap the amount of time spent grunging about on a heavily protected disc */ if ( !isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] The thing behind -w has to be a number! \n") ); exit(1); } sscanf( optarg, "%i", &watchdog_minutes ); if( watchdog_minutes < 1 ) { fprintf( stderr, _("[Hint] Negative minutes aren't allowed - disabling watchdog.\n") ); watchdog_minutes = 0; } break; case'x': /*overwrite all existing files without (further) question */ overwrite_all_flag = TRUE; break; case'F': /*Fast-switch*/ if ( !isdigit( (int) *optarg ) ) { fprintf( stderr, _("[Error] The thing behind -F has to be a number! \n") ); exit(1); } sscanf( optarg, "%i", &fast_factor ); if( fast_factor > BLOCK_COUNT ) /*atm is BLOCK_COUNT == 64 */ { fprintf( stderr, _("[Hint] The largest value for -F is %d at the moment - used that one...\n"), BLOCK_COUNT ); fast_factor = BLOCK_COUNT; } fast_switch = TRUE; break; case'I': /*info, doesn't do anything, but simply prints some infos ( about the dvd )*/ info_flag = TRUE; break; case'L': /*logfile-path (in case your system crashes every time you call vobcopy (and since the normal logs get written to /tmp and that gets cleared at every reboot... )*/ strncpy(logfile_path, optarg, sizeof(logfile_path)-2); /* -s so room for '/' */ strcat(logfile_path, "/"); logfile_path[sizeof(logfile_path)-1] = '\0'; verbose_flag = TRUE; verbosity_level = 2; break; case'O': /*only one file will get copied*/ onefile_flag = TRUE; safestrncpy( onefile, optarg, sizeof(onefile)-1 ); i = 0; /*this i here could be bad... */ while( onefile[ i ] ) { onefile[ i ] = toupper ( onefile[ i ] ); i++; } if( onefile[ i - 1 ] == ',' ) onefile[ i ] = 0; else { onefile[ i ] = ','; onefile[ i + 1 ] = 0; } mirror_flag = TRUE; i = 0; break; case'V': /*version number output */ printf( "Vobcopy "VERSION" - GPL Copyright (c) 2001 - 2009 robos@muon.de\n" ); exit( 0 ); break; case'?': /*probably never gets here, the others should catch it */ fprintf( stderr, _("[Error] Wrong option.\n") ); usage( argv[0] ); exit( 1 ); break; #ifndef HAVE_GETOPT_LONG case'-': /* no getopt, complain */ fprintf( stderr, _("[Error] %s was compiled without support for long options.\n"), argv[0] ); usage( argv[0] ); exit( 1 ); break; #endif default: /*probably never gets here, the others should catch it */ fprintf( stderr, _("[Error] Wrong option.\n") ); usage( argv[0] ); exit( 1 ); } } fprintf( stderr, _("Vobcopy "VERSION" - GPL Copyright (c) 2001 - 2009 robos@muon.de\n") ); fprintf( stderr, _("[Hint] All lines starting with \"libdvdread:\" are not from vobcopy but from the libdvdread-library\n") ); /*get the current working directory*/ if ( provided_output_dir_flag ) { strcpy( pwd, provided_output_dir ); } else { if ( getcwd( pwd, 255 ) == NULL ) { fprintf( stderr, _("\n[Error] Hmm, the path length of your current directory is really large (>255)\n") ); fprintf( stderr, _("[Hint] Change to a path with shorter path length pleeeease ;-)\n") ); exit( 1 ); } } add_end_slash( pwd ); if( quiet_flag ) { int temp; char tmp_path[268]; strcpy( tmp_path, pwd ); strcat( tmp_path, "vobcopy.bla" ); fprintf( stderr, _("[Hint] Quiet mode - All messages will now end up in %s\n"), tmp_path ); if ( ( temp = open( tmp_path , O_RDWR | O_CREAT | O_EXCL, 0666 ) ) == -1 ) { if ( errno == EEXIST ) { if ( !force_flag ) { printf( "[Error] Error: %s\n", strerror( errno ) ); printf( "\n[Error] The file %s already exists. Since overwriting it can be seen as a security problem I stop here.\n", tmp_path ); printf( "[Hint] Use -f to override or simply delete that file\n" ); exit( 1 ); } else { printf( "[Warning] Overwriting %s as requested with -f\n", tmp_path ); } } else { printf( "[Error] Aaah! Re-direct of stderr to %s didn't work! If -f is not used I stop here... \n", tmp_path ); printf( "[Hint] Use -f to continue (at your risk of stupid ascii text ending up in your VOBs)\n" ); if ( !force_flag ) exit( 1 ); } } else { close( temp ); } if ( chmod( tmp_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) == -1 ) { printf( "[Error] Error: %s\n", strerror( errno ) ); printf( "[Error] Changing mode of %s didn't work! If -f is not used I stop here... \n", tmp_path ); printf( "[Hint] Use -f to continue (at your risk of stupid ascii text ending up in your VOBs)\n" ); if ( !force_flag ) exit( 1 ); } /*reopen the already tested file and attach stderr to it*/ if ( freopen( tmp_path , "a" , stderr ) == NULL ) { printf( "[Error] Error: %s\n", strerror( errno ) ); printf( "[Error] Aaah! Re-direct of stderr to %s didn't work! If -f is not used I stop here... \n", tmp_path ); printf( "[Hint] Use -f to continue (at your risk of stupid ascii text ending up in your VOBs)\n" ); if ( !force_flag ) exit( 1 ); } } if( verbosity_level > 1 ) /* this here starts writing the logfile */ { int temp; fprintf( stderr, _("[Info] Uhu, super-verbose\n") ); if( strlen( logfile_path ) < 3 ) strcpy( logfile_path, pwd ); strcpy( logfile_name, "vobcopy_" ); strcat( logfile_name, VERSION ); strcat( logfile_name, ".log" ); strcat( logfile_path, logfile_name ); if ( ( temp = open ( logfile_path , O_RDWR | O_CREAT | O_EXCL, 0666 ) ) == -1 ) { printf( "[Error] Error: %s\n", strerror( errno ) ); if ( errno == EEXIST ) { printf( "\n[Error] The file %s already exists. Since overwriting it can be seen as a security problem I stop here. \n", logfile_path ); printf( "[Hint] Use -f to override or simply delete that file\n" ); if ( !force_flag ) exit( 1 ); } else { printf( "[Error] Aaah! Re-direct of stderr to %s didn't work! If -f is not used I stop here... \n", logfile_path ); if ( !force_flag ) exit( 1 ); } } else { close( temp ); } if ( chmod( logfile_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) == -1 ) { printf( "[Error] Error: %s\n", strerror( errno ) ); printf( "[Error] Changing mode of %s didn't work! If -f is not used I stop here... \n", logfile_path ); printf( "[Hint] Use -f to try to continue anyway\n" ); if ( !force_flag ) exit( 1 ); } fprintf( stderr, _("[Info] The log-file is written to %s\n"), logfile_path ); fprintf( stderr, _("[Hint] Make sure that vobcopy doesn't have to ask questions (like overwriting of old files), these questions end up in the log file so you don't see them...\n") ); fprintf( stderr, _("[Hint] If you don't like that position, use -L /path/to/logfile/ instead of -v -v\n") ); if ( freopen( logfile_path, "a" , stderr ) == NULL ) { printf( "[Error] Error: %s\n", strerror( errno ) ); printf( "[Error] Aaah! Re-direct of stderr to %s didn't work! \n", logfile_path ); /* oh no! redirecting of stderr failed, do best to quit gracefully */ exit( 1 ); } strcpy( vobcopy_call, argv[0] ); for( argc_i = 1; argc_i != argc; argc_i++ ) { strcat( vobcopy_call, " " ); strcat( vobcopy_call, argv[argc_i] ); } fprintf( stderr, _("--------------------------------------------------------------------------------\n") ); fprintf( stderr, _("[Info] Called: %s\n"), vobcopy_call ); } /*sanity check: -m and -n are mutually exclusive... */ if( titleid_flag && mirror_flag ) { fprintf( stderr, _("\n[Error] There can be only one: either -m or -n...'\n") ); exit( 1 ); } /* * Check if the provided path is too long */ if ( optind < argc ) /* there is still the path as in vobcopy-0.2.0 */ { provided_input_dir_flag = TRUE; if ( strlen( argv[optind] ) >= 255 ) { fprintf( stderr, _("\n[Error] Bloody path to long '%s'\n"), argv[optind] ); exit( 1 ); } safestrncpy( provided_input_dir, argv[optind],sizeof(provided_input_dir)-1 ); } if ( provided_input_dir_flag ) /*the path has been given to us */ { int result; /* 'mounted' is an enum, it should not get assigned an int -- lb */ if ( ( result = get_device( provided_input_dir, dvd_path ) ) < 0 ) { fprintf( stderr, _("[Error] Could not get the device which belongs to the given path!\n") ); fprintf( stderr, _("[Hint] Will try to open it as a directory/image file\n") ); /* exit( 1 ); */ } if (result == 0) mounted = FALSE; if (result == 1) mounted = TRUE; } else /*need to get the path and device ourselves ( oyo = on your own ) */ { if ( ( dvd_count = get_device_on_your_own( provided_input_dir, dvd_path ) ) <= 0 ) { fprintf( stderr, _("[Warning] Could not get the device and path! Maybe not mounted the dvd?\n") ); fprintf( stderr, _("[Hint] Will try to open it as a directory/image file\n") ); /* exit( 1 ); */ } if( dvd_count > 0 ) mounted = TRUE; else mounted = FALSE; } if (! mounted ) { /*see if the path given is a iso file or a VIDEO_TS dir */ safestrncpy( dvd_path, provided_input_dir, sizeof(dvd_path)-1 ); } /* * Is the path correct */ fprintf( stderr, _("\n[Info] Path to dvd: %s\n"), dvd_path ); if( !( dvd = DVDOpen( dvd_path ) ) ) { fprintf( stderr, _("\n[Error] Path thingy didn't work '%s'\n"), dvd_path); fprintf( stderr, _("[Error] Try something like -i /cdrom, /dvd or /mnt/dvd \n") ); if( dvd_count > 1 ) fprintf( stderr, _("[Hint] By the way, you have %i cdroms|dvds mounted, that probably caused the problem\n"), dvd_count ); DVDClose( dvd ); exit( 1 ); } /* * this here gets the dvd name */ if ( provided_dvd_name_flag ) safestrncpy( dvd_name, provided_dvd_name, sizeof(dvd_name)-1 ); else get_dvd_name_return = get_dvd_name( dvd_path, dvd_name ); fprintf( stderr, _("[Info] Name of the dvd: %s\n"), dvd_name ); /* The new part taken from play-title.c*/ /** * Load the video manager to find out the information about the titles on * this disc. */ vmg_file = ifoOpen( dvd, 0 ); if( !vmg_file ) { fprintf( stderr, _("[Error] Can't open VMG info.\n") ); DVDClose( dvd ); return -1; } tt_srpt = vmg_file->tt_srpt; /** * Get the title with the most chapters since this is probably the main part */ for( i = 0;i < tt_srpt->nr_of_srpts;i++ ) { sum_chapters += tt_srpt->title[ i ].nr_of_ptts; if( i > 0 ) { if( tt_srpt->title[ i ].nr_of_ptts > tt_srpt->title[ most_chapters ].nr_of_ptts ) { most_chapters = i; } } } if( longest_title_flag ) /*no title specified (-n ) */ { titleid = get_longest_title( &dvd ); fprintf( stderr, _("[Info] longest title %d.\n"), titleid ); } if( !titleid_flag ) /*no title specified (-n ) */ { titleid = most_chapters + 1; /*they start counting with 0, I with 1...*/ } /** * Make sure our title number is valid. */ fprintf( stderr, _("[Info] There are %d titles on this DVD.\n"), tt_srpt->nr_of_srpts ); if( titleid <= 0 || ( titleid-1 ) >= tt_srpt->nr_of_srpts ) { fprintf( stderr, _("[Error] Invalid title %d.\n"), titleid ); ifoClose( vmg_file ); DVDClose( dvd ); return -1; } /** * Make sure the chapter number is valid for this title. */ fprintf( stderr, _("[Info] There are %i chapters on the dvd.\n"), sum_chapters ); fprintf( stderr, _("[Info] Most chapters has title %i with %d chapters.\n"), ( most_chapters + 1 ), tt_srpt->title[ most_chapters ].nr_of_ptts ); if( info_flag ) { fprintf( stderr, _("[Info] All titles:\n") ); for( i = 0;i < tt_srpt->nr_of_srpts;i++ ) { int chapters = tt_srpt->title[ i ].nr_of_ptts; if( chapters > 1 ) fprintf( stderr, _("[Info] Title %i has %d chapters.\n"), ( i+1 ), chapters ); else fprintf( stderr, _("[Info] Title %i has %d chapter.\n"), ( i+1 ), chapters ); } } if( chapid < 0 || chapid >= tt_srpt->title[ titleid-1 ].nr_of_ptts ) { fprintf( stderr, _("[Error] Invalid chapter %d\n"), chapid + 1 ); ifoClose( vmg_file ); DVDClose( dvd ); return -1; } /** * Make sure the angle number is valid for this title. */ for( i = 0;i < tt_srpt->nr_of_srpts;i++ ) { sum_angles += tt_srpt->title[ i ].nr_of_angles; } fprintf( stderr, _("\n[Info] There are %d angles on this dvd.\n"), sum_angles ); if( angle < 0 || angle >= tt_srpt->title[ titleid-1 ].nr_of_angles ) { fprintf( stderr, _("[Error] Invalid angle %d\n"), angle + 1 ); ifoClose( vmg_file ); DVDClose( dvd ); return -1; } if( info_flag ) { fprintf( stderr, _("[Info] All titles:\n") ); for(i = 0;i < tt_srpt->nr_of_srpts;i++ ) { int angles = tt_srpt->title[ i ].nr_of_angles; if( angles > 1 ) fprintf( stderr, _("[Info] Title %i has %d angles.\n"), ( i+1 ), angles ); else fprintf( stderr, _("[Info] Title %i has %d angle.\n"), ( i+1 ), angles ); } disk_vob_size = get_used_space( provided_input_dir, verbosity_level ); } /* * get the whole vob size via stat( ) manually */ if( mounted && !mirror_flag ) { vob_size = ( get_vob_size( titleid, provided_input_dir ) ) - ( seek_start * 2048 ) - ( stop_before_end * 2048 ); if( vob_size == 0 || vob_size > 9663676416LL) /*9663676416 equals 9GB */ { fprintf( stderr, _("\n[Error] Something went wrong during the size detection of the") ); fprintf( stderr, _("\n[Error] vobs, size check at the end won't work (probably), but I continue anyway\n\n") ); vob_size = 0; } } if( mirror_flag ) /* this gets the size of the whole dvd */ { add_end_slash( provided_input_dir ); disk_vob_size = get_used_space( provided_input_dir, verbosity_level ); /* vob_size = get_free_space( provided_input_dir,verbosity_level ); */ } /* * check if on the target directory is enough space free * see man statfs for more info */ pwd_free = get_free_space( pwd,verbosity_level ); if( fast_switch ) block_count = fast_factor; else block_count = 1; install_signal_handlers(); if( watchdog_minutes ) { fprintf( stderr, _("\n[Info] Setting watchdog timer to %d minutes\n"), watchdog_minutes ); alarm( watchdog_minutes * 60 ); } /*** this is the mirror section ***/ if( mirror_flag ) {/*mirror beginning*/ fprintf( stderr, _("\n[Info] DVD-name: %s\n"), dvd_name ); if( provided_dvd_name_flag ) { fprintf( stderr, _("\n[Info] Your name for the dvd: %s\n"), provided_dvd_name ); safestrncpy( dvd_name, provided_dvd_name, sizeof(dvd_name)-1 ); } fprintf( stderr, _("[Info] Disk free: %.0f MB\n"), (float) pwd_free / ( 1024*1024 ) ); fprintf( stderr, _("[Info] Vobs size: %.0f MB\n"), (float) disk_vob_size / ( 1024*1024 ) ); if( ( force_flag || pwd_free > disk_vob_size ) && alternate_dir_count < 2 ) /* no dirs behind -1, -2 ... since its all in one dir */ { char video_ts_dir[263]; char number[8]; char input_file[280]; char output_file[255]; int i, start, title_nr = 0; off_t file_size; double tmp_i = 0, tmp_file_size = 0; int k = 0; char d_name[256]; safestrncpy( name, pwd, sizeof(name)-34 ); /* 255 */ strncat( name, dvd_name, 33 ); if( !stdout_flag ) { makedir ( name ); strcat( name, "/VIDEO_TS/" ); makedir ( name ); fprintf( stderr, _("[Info] Writing files to this dir: %s\n"), name ); } /*TODO: substitute with open_dir function */ strcpy( video_ts_dir, provided_input_dir ); strcat( video_ts_dir, "video_ts"); /*it's either video_ts */ dir = opendir( video_ts_dir ); /*or VIDEO_TS*/ if ( dir == NULL ) { strcpy( video_ts_dir, provided_input_dir ); strcat( video_ts_dir, "VIDEO_TS"); dir = opendir( video_ts_dir ); if ( dir == NULL ) { fprintf( stderr, _("[Error] Hmm, weird, the dir video_ts|VIDEO_TS on the dvd couldn't be opened\n")); fprintf( stderr, _("[Error] The dir to be opened was: %s\n"), video_ts_dir ); fprintf( stderr, _("[Hint] Please mail me what your vobcopy call plus -v -v spits out\n")); exit( 1 ); } } directory = readdir( dir ); /* thats the . entry */ directory = readdir( dir ); /* thats the .. entry */ /* according to the file type (vob, ifo, bup) the file gets copied */ while( ( directory = readdir( dir ) ) != NULL ) {/*main mirror loop*/ k = 0; safestrncpy( output_file, name, sizeof(output_file)-1 ); /*in dvd specs it says it must be uppercase VIDEO_TS/VTS... but iso9660 mounted dvd's sometimes have it lowercase */ while( directory->d_name[k] ) { d_name[k] = toupper (directory->d_name[k] ); k++; } d_name[k] = 0; /*in order to copy only _one_ file */ /* if( onefile_flag ) { if( !strstr( onefile, d_name ) ) maybe other way around*/ /* continue; }*/ /*in order to copy only _one_ file and do "globbing" a la: -O 02 will copy vts_02_1, vts_02_2 ... all that have 02 in it*/ if( onefile_flag ) { char *tokenpos, *tokenpos1; char tmp[12]; tokenpos = onefile; if( strstr( tokenpos, "," ) ) { while( ( tokenpos1 = strstr( tokenpos, "," ) ) ) /*tokens separated by , */ { /*this parses every token without modifying the onefile var */ int len_begin; len_begin = tokenpos1 - tokenpos; safestrncpy( tmp, tokenpos, len_begin ); tokenpos = tokenpos1 + 1; tmp[ len_begin ] = '\0'; if( strstr( d_name, tmp ) ) goto next; /*if the token is found in the d_name copy */ else continue; /* next token is tested */ } continue; /*no token matched, next d_name is tested */ } else { if( !strstr( d_name, onefile ) ) /*maybe other way around */ { continue; } else goto next; /*if the token is found in the d_name copy */ continue; /*no token matched, next d_name is tested */ } } next: /*for the goto - ugly, I know... */ if( stdout_flag ) /*this writes to stdout*/ { streamout = STDOUT_FILENO; /*in other words: 1, see "man stdout" */ } else { if( strstr( d_name, ";?" ) ) { fprintf( stderr, _("\n[Hint] File on dvd ends in \";?\" (%s)\n"), d_name ); strncat( output_file, d_name, strlen( d_name ) - 2 ); } else { strcat( output_file, d_name ); } fprintf( stderr, _("[Info] Writing to %s \n"), output_file); if( open( output_file, O_RDONLY ) >= 0 ) { bool bSkip = FALSE; if ( overwrite_all_flag == FALSE ) fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all, [s]kip or [q]uit? "), output_file ); /*TODO: add [a]ppend and seek thought stream till point of append is there */ while ( 1 ) { /* process a single character from stdin, ignore EOF bytes & newlines*/ if ( overwrite_all_flag == TRUE ) op = 'o'; else do { op = fgetc (stdin); } while(op == EOF || op == '\n'); if( op == 'o' || op == 'x' ) { if( ( streamout = open( output_file, O_WRONLY | O_TRUNC ) ) < 0 ) { fprintf( stderr, _("\n[Error] Error opening file %s\n"), output_file ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit ( 1 ); } else close (streamout); overwrite_flag = TRUE; if( op == 'x' ) { overwrite_all_flag = TRUE; } break; } else if( op == 'q' ) { DVDCloseFile( dvd_file ); DVDClose( dvd ); exit( 1 ); } else if( op == 's' ) { bSkip = TRUE; break; } else { fprintf( stderr, _("\n[Hint] Please choose [o]verwrite, [x]overwrite all, [s]kip, or [q]uit the next time ;-)\n") ); } } if( bSkip ) continue; /* next file, please! */ } strcat( output_file, ".partial" ); if( open( output_file, O_RDONLY ) >= 0 ) { if ( overwrite_all_flag == FALSE ) fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all or [q]uit? \n"), output_file ); /*TODO: add [a]ppend and seek thought stream till point of append is there */ while ( 1 ) { if ( overwrite_all_flag == TRUE ) op = 'o'; else { while ((op = fgetc (stdin)) == EOF) usleep (1); fgetc ( stdin ); /* probably need to do this for second time it comes around this loop */ } if( op == 'o' || op == 'x' ) { if( ( streamout = open( output_file, O_WRONLY | O_TRUNC ) ) < 0 ) { fprintf( stderr, _("\n[Error] Error opening file %s\n"), output_file ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit ( 1 ); } /* else close( streamout ); */ overwrite_flag = TRUE; if ( op == 'x' ) { overwrite_all_flag = TRUE; } break; } else if( op == 'q' ) { DVDCloseFile( dvd_file ); DVDClose( dvd ); exit( 1 ); } else { fprintf( stderr, _("\n[Hint] Please choose [o]verwrite, [x]overwrite all or [q]uit the next time ;-)\n") ); } } } else { /*assign the stream */ if( ( streamout = open( output_file, O_WRONLY | O_CREAT, 0644 ) ) < 0 ) { fprintf( stderr, _("\n[Error] Error opening file %s\n"), output_file ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit ( 1 ); } } } /* get the size of that file*/ strcpy( input_file, video_ts_dir ); strcat( input_file, "/" ); strcat( input_file, directory->d_name ); stat( input_file, &buf ); file_size = buf.st_size; tmp_file_size = file_size; memset( bufferin, 0, DVD_VIDEO_LB_LEN * sizeof( unsigned char ) ); /*this here gets the title number*/ for( i = 1; i <= 99; i++ ) /*there are 100 titles, but 0 is named video_ts, the others are vts_number_0.bup */ { sprintf(number, "_%.2i", i); if ( strstr( directory->d_name, number ) ) { title_nr = i; break; /*number found, is in i now*/ } /*no number -> video_ts is the name -> title_nr = 0*/ } /*which file type is it*/ if( strstr( directory->d_name, ".bup" ) || strstr( directory->d_name, ".BUP" ) ) { dvd_file = DVDOpenFile( dvd, title_nr, DVD_READ_INFO_BACKUP_FILE ); /*this copies the data to the new file*/ for( i = 0; i*DVD_VIDEO_LB_LEN < file_size; i++) { DVDReadBytes( dvd_file, bufferin, DVD_VIDEO_LB_LEN ); if( write( streamout, bufferin, DVD_VIDEO_LB_LEN ) < 0 ) { fprintf( stderr, _("\n[Error] Error writing to %s \n"), output_file ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit( 1 ); } /* progress indicator */ tmp_i = i; fprintf( stderr, _("%4.0fkB of %4.0fkB written\r"), ( tmp_i+1 )*( DVD_VIDEO_LB_LEN/1024 ), tmp_file_size/1024 ); } fprintf( stderr, _("\n")); if( !stdout_flag ) { if( fdatasync( streamout ) < 0 ) { fprintf( stderr, _("\n[Error] error writing to %s \n"), output_file ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); exit( 1 ); } close( streamout ); re_name( output_file ); } } if( strstr( directory->d_name, ".ifo" ) || strstr( directory->d_name, ".IFO" ) ) { dvd_file = DVDOpenFile( dvd, title_nr, DVD_READ_INFO_FILE ); /*this copies the data to the new file*/ for( i = 0; i*DVD_VIDEO_LB_LEN < file_size; i++) { DVDReadBytes( dvd_file, bufferin, DVD_VIDEO_LB_LEN ); if( write( streamout, bufferin, DVD_VIDEO_LB_LEN ) < 0 ) { fprintf( stderr, _("\n[Error] Error writing to %s \n"), output_file ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit( 1 ); } /* progress indicator */ tmp_i = i; fprintf( stderr, _("%4.0fkB of %4.0fkB written\r"), ( tmp_i+1 )*( DVD_VIDEO_LB_LEN/1024 ), tmp_file_size/1024 ); } fprintf( stderr, _("\n")); if( !stdout_flag ) { if( fdatasync( streamout ) < 0 ) { fprintf( stderr, _("\n[Error] error writing to %s \n"), output_file ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); exit( 1 ); } close( streamout ); re_name( output_file ); } } if( strstr( directory->d_name, ".vob" ) || strstr( directory->d_name, ".VOB" ) ) { if( directory->d_name[7] == 48 || title_nr == 0 ) { /*this is vts_xx_0.vob or video_ts.vob, a menu vob*/ dvd_file = DVDOpenFile( dvd, title_nr, DVD_READ_MENU_VOBS ); start = 0 ; } else { dvd_file = DVDOpenFile( dvd, title_nr, DVD_READ_TITLE_VOBS ); } if( directory->d_name[7] == 49 || directory->d_name[7] == 48 ) /* 49 means in ascii 1 and 48 0 */ { /* reset start when at beginning of Title */ start = 0 ; } if( directory->d_name[7] > 49 && directory->d_name[7] < 58 ) /* 49 means in ascii 1 and 58 : (i.e. over 9)*/ { off_t culm_single_vob_size = 0; int a, subvob; subvob = ( directory->d_name[7] - 48 ); for( a = 1; a < subvob; a++ ) { if( strstr( input_file, ";?" ) ) input_file[ strlen( input_file ) - 7 ] = ( a + 48 ); else input_file[ strlen( input_file ) - 5 ] = ( a + 48 ); /* input_file[ strlen( input_file ) - 5 ] = ( a + 48 );*/ if( stat( input_file, &buf ) < 0 ) { fprintf( stderr, _("[Info] Can't stat() %s.\n"), input_file ); exit( 1 ); } culm_single_vob_size += buf.st_size; if( verbosity_level > 1 ) fprintf( stderr, _("[Info] Vob %d %d (%s) has a size of %lli\n"), title_nr, subvob, input_file, buf.st_size ); } start = ( culm_single_vob_size / DVD_VIDEO_LB_LEN ); /* start = ( ( ( directory->d_name[7] - 49 ) * 512 * 1024 ) - ( directory->d_name[7] - 49 ) ); */ /* this here seeks d_name[7] (which is the 3 in vts_01_3.vob) Gigabyte (which is equivalent to 512 * 1024 blocks (a block is 2kb) in the dvd stream in order to reach the 3 in the above example. * NOT! the sizes of the "1GB" files aren't 1GB... */ } /*this copies the data to the new file*/ if( verbosity_level > 1) fprintf( stderr, _("[Info] Start of %s at %d blocks \n"), output_file, start ); file_block_count = block_count; starttime = time(NULL); for( i = start; ( i - start ) * DVD_VIDEO_LB_LEN < file_size; i += file_block_count) { int tries = 0, skipped_blocks = 0; /* Only read and write as many blocks as there are left in the file */ if ( ( i - start + file_block_count ) * DVD_VIDEO_LB_LEN > file_size ) { file_block_count = ( file_size / DVD_VIDEO_LB_LEN ) - ( i - start ); } /* DVDReadBlocks( dvd_file, i, 1, bufferin );this has to be wrong with the 1 there...*/ while( ( blocks = DVDReadBlocks( dvd_file, i, file_block_count, bufferin ) ) <= 0 && tries < 10 ) { if( tries == 9 ) { i += file_block_count; skipped_blocks +=1; overall_skipped_blocks +=1; tries=0; } /* if( verbosity_level >= 1 ) fprintf( stderr, _("[Warn] Had to skip %d blocks (reading block %d)! \n "), skipped_blocks, i ); */ tries++; } if( verbosity_level >= 1 && skipped_blocks > 0 ) fprintf( stderr, _("[Warn] Had to skip (couldn't read) %d blocks (before block %d)! \n "), skipped_blocks, i ); /*TODO: this skipping here writes too few bytes to the output */ if( write( streamout, bufferin, DVD_VIDEO_LB_LEN * blocks ) < 0 ) { fprintf( stderr, _("\n[Error] Error writing to %s \n"), output_file ); fprintf( stderr, _("[Error] Error: %s, errno: %d \n"), strerror( errno ), errno ); exit( 1 ); } /*progression bar*/ /*this here doesn't work with -F 10 */ /* if( !( ( ( ( i-start )+1 )*DVD_VIDEO_LB_LEN )%( 1024*1024 ) ) ) */ progressUpdate(starttime, (int)(( ( i-start+1 )*DVD_VIDEO_LB_LEN )), (int)(tmp_file_size+2048), FALSE); /* if( check_progress() ) { tmp_i = ( i-start ); percent = ( ( ( ( tmp_i+1 )*DVD_VIDEO_LB_LEN )*100 )/tmp_file_size ); fprintf( stderr, _("\r%4.0fMB of %4.0fMB written "), ( ( tmp_i+1 )*DVD_VIDEO_LB_LEN )/( 1024*1024 ), ( tmp_file_size+2048 )/( 1024*1024 ) ); fprintf( stderr, _("( %3.1f %% ) "), percent ); } */ } /*this is just so that at the end it actually says 100.0% all the time... */ /*TODO: if it is correct to always assume it's 100% is a good question.... */ /* fprintf( stderr, _("\r%4.0fMB of %4.0fMB written "), ( ( tmp_i+1 )*DVD_VIDEO_LB_LEN )/( 1024*1024 ), ( tmp_file_size+2048 )/( 1024*1024 ) ); fprintf( stderr, _("( 100.0%% ) ") ); */ lastpos = 0; progressUpdate(starttime, (int)(( ( i-start+1 )*DVD_VIDEO_LB_LEN )), (int)(tmp_file_size+2048), TRUE); start=i; fprintf( stderr, _("\n") ); if( !stdout_flag ) { if( fdatasync( streamout ) < 0 ) { fprintf( stderr, _("\n[Error] error writing to %s \n"), output_file ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); exit( 1 ); } close( streamout ); re_name( output_file ); } } } ifoClose( vmg_file ); DVDCloseFile( dvd_file ); DVDClose( dvd ); if ( overall_skipped_blocks > 0 ) fprintf( stderr, _("[Info] %d blocks had to be skipped, be warned.\n"), overall_skipped_blocks ); exit( 0 ); } else { fprintf( stderr, _("[Error] Not enough free space on the destination dir. Please choose another one or -f\n") ); fprintf( stderr, _("[Error] or dirs behind -1, -2 ... are NOT allowed with -m!\n") ); exit( 1 ); } } /*end of mirror block*/ /* * Open now up the actual files for reading * they come from libdvdread merged together under the given title number * (thx again for the great library) */ fprintf( stderr, _("[Info] Using Title: %i\n"), titleid ); fprintf( stderr, _("[Info] Title has %d chapters and %d angles\n"),tt_srpt->title[ titleid - 1 ].nr_of_ptts,tt_srpt->title[ titleid - 1 ].nr_of_angles ); fprintf( stderr, _("[Info] Using Chapter: %i\n"), chapid + 1 ); fprintf( stderr, _("[Info] Using Angle: %i\n"), angle + 1 ); if( info_flag && vob_size != 0 ) { fprintf( stderr, _("\n[Info] DVD-name: %s\n"), dvd_name ); fprintf( stderr, _("[Info] Disk free: %f MB\n"), (double) (pwd_free / ( 1024.0*1024.0 )) ); fprintf( stderr, _("[Info] Vobs size: %f MB\n"), (double) vob_size / ( 1024.0*1024.0 ) ); ifoClose( vmg_file ); DVDCloseFile( dvd_file ); DVDClose( dvd ); /*hope all are closed now...*/ exit( 0 ); } /** * Load the VTS information for the title set our title is in. */ vts_file = ifoOpen( dvd, tt_srpt->title[ titleid-1 ].title_set_nr ); if( !vts_file ) { fprintf( stderr, _("[Error] Can't open the title %d info file.\n"), tt_srpt->title[ titleid-1 ].title_set_nr ); ifoClose( vmg_file ); DVDClose( dvd ); return -1; } /** * Determine which program chain we want to watch. This is based on the * chapter number. */ ttn = tt_srpt->title[ titleid-1 ].vts_ttn; vts_ptt_srpt = vts_file->vts_ptt_srpt; pgc_id = vts_ptt_srpt->title[ ttn - 1 ].ptt[ chapid ].pgcn; pgn = vts_ptt_srpt->title[ ttn - 1 ].ptt[ chapid ].pgn; cur_pgc = vts_file->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc; start_cell = cur_pgc->program_map[ pgn - 1 ] - 1; /** * We've got enough info, time to open the title set data. */ dvd_file = DVDOpenFile( dvd, tt_srpt->title[ titleid-1 ].title_set_nr, DVD_READ_TITLE_VOBS ); if( !dvd_file ) { fprintf( stderr, _("[Error] Can't open title VOBS (VTS_%02d_1.VOB).\n"), tt_srpt->title[ titleid-1 ].title_set_nr ); ifoClose( vts_file ); ifoClose( vmg_file ); DVDClose( dvd ); return -1; } file_size_in_blocks = DVDFileSize( dvd_file ); if ( vob_size == ( - ( seek_start * 2048 ) - ( stop_before_end * 2048 ) ) ) { vob_size = ( ( off_t ) ( file_size_in_blocks ) * ( off_t ) DVD_VIDEO_LB_LEN ) - ( seek_start * 2048 ) - ( stop_before_end * 2048 ); if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] Vob_size was 0\n") ); } /*debug-output: difference between vobsize read from cd and size returned from libdvdread */ if ( mounted && verbose_flag ) { fprintf( stderr, _("\n[Info] Difference between vobsize read from cd and size returned from libdvdread:\n") ); /* fprintf( stderr, _("vob_size (stat) = %lu\nlibdvdsize = %lu\ndiff = %lu\n"), TODO:the diff returns only crap... vob_size, ( off_t ) ( file_size_in_blocks ) * ( off_t ) DVD_VIDEO_LB_LEN, ( off_t ) vob_size - ( off_t ) ( ( off_t )( file_size_in_blocks ) * ( off_t ) ( DVD_VIDEO_LB_LEN ) ) ); */ fprintf( stderr, _("[Info] Vob_size (stat) = %lu\n[Info] libdvdsize = %lu\n"), (long unsigned int) vob_size, (long unsigned int)(( off_t ) ( file_size_in_blocks ) * ( off_t ) DVD_VIDEO_LB_LEN )); } if( info_flag ) { fprintf( stderr, _("\n[Info] DVD-name: %s\n"), dvd_name ); fprintf( stderr, _("[Info] Disk free: %.0f MB\n"), ( float ) (pwd_free / (1024 * 1024)) ); /* Should be the *disk* size here, right? -- lb */ fprintf( stderr, _("[Info] Vobs size: %.0f MB\n"), ( float ) (disk_vob_size / (1024 * 1024 )) ); ifoClose( vts_file ); ifoClose( vmg_file ); DVDCloseFile( dvd_file ); DVDClose( dvd ); /*hope all are closed now...*/ exit( 0 ); } /* now the actual check if enough space is free*/ if ( pwd_free < vob_size ) { fprintf( stderr, _("\n[Info] Disk free: %.0f MB"), (float) pwd_free / ( 1024*1024 ) ); fprintf( stderr, _("\n[Info] Vobs size: %.0f MB"), (float) vob_size / ( 1024*1024 ) ); if( !force_flag ) fprintf( stderr, _("\n[Error] Hmm, better change to a dir with enough space left or call with -f (force) \n") ); if( pwd_free == 0 && !force_flag ) { if( verbosity_level > 1 ) fprintf( stderr, _("[Error] Hmm, statfs (statvfs) seems not to work on that directory. \n") ); fprintf( stderr, _("[Error] Hmm, statfs (statvfs) seems not to work on that directory. \n") ); fprintf( stderr, _("[Hint] Nevertheless, do you want vobcopy to continue [y] or do you want to check for \n") ); fprintf( stderr, _("[Hint] enough space first [q]?\n") ); while ( 1 ) { while ((op = fgetc (stdin)) == EOF) usleep (1); if( op == 'y' ) { force_flag = TRUE; if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] y pressed - force write\n") ); break; } else if( op == 'n' || op =='q' ) { if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] n/q pressed\n") ); exit( 1 ); break; } else { fprintf( stderr, _("[Error] Please choose [y] to continue or [n] to quit\n") ); } } } if ( !force_flag ) exit( 1 ); } /* from alt.tasteless.jokes: A farmer walks into his bedroom with a sheep under his arm. "Honey, this pig is what I fuck when you don't feel well." The wife looks up from the magazine she's reading and says, "That's not a pig, it's a sheep." The man replies, "I was talking to the sheep." */ /********************* * this is the main read and copy loop *********************/ fprintf( stderr, _("\n[Info] DVD-name: %s\n"), dvd_name ); if( provided_dvd_name_flag && !stdout_flag ) /*if the user has given a name for the file */ { fprintf( stderr, _("\n[Info] Your name for the dvd: %s\n"), provided_dvd_name ); safestrncpy( dvd_name, provided_dvd_name, sizeof(dvd_name)-1 ); } while( offset < ( file_size_in_blocks - seek_start - stop_before_end ) ) { partcount++; if( !stdout_flag ) /*if the stream doesn't get written to stdout*/ { /*part to distribute the files over different directories*/ if( paths_taken == 0 ) { add_end_slash( pwd ); free_space = get_free_space( pwd, verbosity_level ); if( verbosity_level > 1 ) fprintf( stderr, _("[Info] Free space for -o dir: %.0f\n"), ( float ) free_space ); if( large_file_flag ) make_output_path( pwd,name,get_dvd_name_return,dvd_name,titleid, -1 ); else make_output_path( pwd,name,get_dvd_name_return,dvd_name,titleid, partcount ); } else { for( i = 1; i < alternate_dir_count; i++ ) { if( paths_taken == i ) { add_end_slash( alternate_output_dir[ i-1 ] ); free_space = get_free_space( alternate_output_dir[ i-1 ],verbosity_level ); if( verbosity_level > 1 ) fprintf( stderr, _("[Info] Free space for -%i dir: %.0f\n"), i, ( float ) free_space ); if ( large_file_flag ) make_output_path( alternate_output_dir[ i-1 ], name, get_dvd_name_return, dvd_name, titleid, -1 ); else make_output_path( alternate_output_dir[ i-1 ], name, get_dvd_name_return, dvd_name, titleid,partcount ); /* alternate_dir_count--; */ } } } /*here the output size gets adjusted to the given free space*/ if( !large_file_flag && force_flag && free_space < 2147473408 ) /* 2GB */ { space_greater_2gb_flag = FALSE; max_filesize_in_blocks = ( ( free_space - 2097152 ) / 2048 ); /* - 2 MB */ if( verbosity_level > 1 ) fprintf( stderr, _("[Info] Taken max_filesize_in_blocks(2GB version): %.0f\n"), ( float ) max_filesize_in_blocks ); paths_taken++; } else if( large_file_flag && force_flag) /*lfs version */ { space_greater_2gb_flag = FALSE; max_filesize_in_blocks = ( ( free_space - 2097152) / 2048);/* - 2 MB */ if( verbosity_level > 1) fprintf( stderr, _("[Info] Taken max_filesize_in_blocks(lfs version): %.0f\n"), ( float ) max_filesize_in_blocks ); paths_taken++; } else if( !large_file_flag ) { max_filesize_in_blocks = 1048571; /*if free_space is more than 2 GB fall back to max_filesize_in_blocks=2GB*/ space_greater_2gb_flag = TRUE; } if( open( name, O_RDONLY ) >= 0 ) { if ( overwrite_all_flag == FALSE ) fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all or [q]uit? \n"), name ); /*TODO: add [a]ppend and seek thought stream till point of append is there */ while ( 1 ) { if ( overwrite_all_flag == TRUE ) op = 'o'; else { while ((op = fgetc (stdin)) == EOF) usleep (1); fgetc ( stdin ); /* probably need to do this for second time it comes around this loop */ } if( op == 'o' || op == 'x' ) { if( ( streamout = open( name, O_WRONLY | O_TRUNC ) ) < 0 ) { fprintf( stderr, _("\n[Error] Error opening file %s\n"), name ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit ( 1 ); } else close( streamout ); overwrite_flag = TRUE; if ( op == 'x' ) { overwrite_all_flag = TRUE; } break; } else if( op == 'q' ) { DVDCloseFile( dvd_file ); DVDClose( dvd ); exit( 1 ); } else { fprintf( stderr, _("\n[Hint] please choose [o]verwrite, [x]overwrite all or [q]uit the next time ;-)\n") ); } } } strcat( name, ".partial" ); #if defined( HAS_LARGEFILE ) if( open( name, O_RDONLY|O_LARGEFILE ) >= 0 ) #else if( open( name, O_RDONLY ) >= 0 ) #endif { if ( get_free_space( name, verbosity_level ) < 2097152 ) /* it might come here when the platter is full after a -f */ { fprintf( stderr, _("[Error] Seems your platter is full...\n")); exit ( 1 ); } if ( overwrite_all_flag == FALSE ) fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all, [a]ppend, [q]uit? \n"), name ); while ( 1 ) { if ( overwrite_all_flag == TRUE ) op = 'o'; else { while ((op = fgetc (stdin)) == EOF) usleep (1); fgetc ( stdin ); /* probably need to do this for second time it comes around this loop */ } if( op == 'o' || op == 'x' ) { #if defined( HAS_LARGEFILE ) if( ( streamout = open( name, O_WRONLY | O_TRUNC | O_LARGEFILE ) ) < 0 ) #else if( ( streamout = open( name, O_WRONLY | O_TRUNC ) ) < 0 ) #endif { fprintf( stderr, _("\n[Error] Error opening file %s\n"), name ); exit ( 1 ); } /* else close (streamout); */ overwrite_flag = TRUE; if ( op == 'x' ) { overwrite_all_flag = TRUE; } break; } else if( op == 'a' ) { #if defined( HAS_LARGEFILE ) if( ( streamout = open( name, O_WRONLY | O_APPEND | O_LARGEFILE ) ) < 0 ) #else if( ( streamout = open( name, O_WRONLY | O_APPEND ) ) < 0 ) #endif { fprintf( stderr, _("\n[Error] Error opening file %s\n"), name ); exit ( 1 ); } /* else close( streamout ); */ if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] User chose append\n") ); break; } else if( op == 'q' ) { DVDCloseFile( dvd_file ); DVDClose( dvd ); exit( 1 ); } else { fprintf( stderr, _("\n[Hint] Please choose [o]verwrite, [x]overwrite all, [a]ppend, [q]uit the next time ;-)\n") ); } } } else { /*assign the stream */ #if defined( HAS_LARGEFILE ) if( ( streamout = open( name, O_WRONLY | O_CREAT | O_LARGEFILE, 0644 ) ) < 0 ) #else if( ( streamout = open( name, O_WRONLY | O_CREAT, 0644 ) ) < 0 ) #endif { fprintf( stderr, _("\n[Error] Error opening file %s\n"), name ); exit ( 1 ); } } } if( stdout_flag ) /*this writes to stdout*/ { streamout = STDOUT_FILENO; /*in other words: 1, see "man stdout" */ } /* this here is the main copy part */ fprintf( stderr, _("\n") ); memset( bufferin, 0, BLOCK_COUNT * DVD_VIDEO_LB_LEN * sizeof( unsigned char ) ); file_block_count = block_count; starttime = time(NULL); for ( ; ( offset + ( off_t ) seek_start ) < ( ( off_t ) file_size_in_blocks - ( off_t ) stop_before_end ) && offset - ( off_t )max_filesize_in_blocks_summed - (off_t)angle_blocks_skipped < max_filesize_in_blocks; offset += file_block_count ) { int tries = 0, skipped_blocks = 0; /* Only read and write as many blocks as there are left in the file */ if ( ( offset + file_block_count + ( off_t ) seek_start ) > ( ( off_t ) file_size_in_blocks - ( off_t ) stop_before_end ) ) { file_block_count = ( off_t ) file_size_in_blocks - ( off_t ) stop_before_end - offset - ( off_t ) seek_start; } if ( offset + file_block_count - ( off_t )max_filesize_in_blocks_summed - (off_t)angle_blocks_skipped > max_filesize_in_blocks ) { file_block_count = max_filesize_in_blocks - ( offset + file_block_count - ( off_t )max_filesize_in_blocks_summed - (off_t)angle_blocks_skipped ); } /* blocks = DVDReadBlocks( dvd_file,( offset + seek_start ), file_block_count, bufferin ); */ while( ( blocks = DVDReadBlocks( dvd_file,( offset + seek_start ), file_block_count, bufferin ) ) <= 0 && tries < 10 ) { if( tries == 9 ) { offset += file_block_count; skipped_blocks +=1; overall_skipped_blocks +=1; tries=0; } /* if( verbosity_level >= 1 ) fprintf( stderr, _("[Warn] Had to skip %d blocks (reading block %d)! \n "), skipped_blocks, i ); */ tries++; } if( verbosity_level >= 1 && skipped_blocks > 0 ) fprintf( stderr, _("[Warn] Had to skip (couldn't read) %d blocks (before block %d)! \n "), skipped_blocks, offset ); /*TODO: this skipping here writes too few bytes to the output */ if( write( streamout, bufferin, DVD_VIDEO_LB_LEN * blocks ) < 0 ) { fprintf( stderr, _("\n[Error] Write() error\n") ); fprintf( stderr, _("[Error] It's possible that you try to write files\n") ); fprintf( stderr, _("[Error] greater than 2GB to filesystem which\n") ); fprintf( stderr, _("[Error] doesn't support it? (try without -l)\n") ); fprintf( stderr, _("[Error] Error: %s\n"), strerror( errno ) ); exit( 1 ); } /*this is for people who report that it takes vobcopy ages to copy something */ /* TODO */ progressUpdate(starttime, (int)offset/512, (int)( file_size_in_blocks - seek_start - stop_before_end )/512, FALSE); } if( !stdout_flag ) { if( fdatasync( streamout ) < 0 ) { fprintf( stderr, _("\n[Error] error writing to %s \n"), name ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); exit( 1 ); } progressUpdate(starttime, (int)offset/512, (int)( file_size_in_blocks - seek_start - stop_before_end )/512, TRUE); close( streamout ); if( verbosity_level >= 1 ) { fprintf( stderr, _("[Info] max_filesize_in_blocks %8.0f \n"), ( float ) max_filesize_in_blocks ); fprintf( stderr, _("[Info] offset at the end %8.0f \n"), ( float ) offset ); fprintf( stderr, _("[Info] file_size_in_blocks %8.0f \n"),( float ) file_size_in_blocks ); } /* now lets see whats the size of this file in bytes */ stat( name, &buf ); disk_vob_size += ( off_t ) buf.st_size; if( large_file_flag && !cut_flag ) { if( ( vob_size - disk_vob_size ) < MAX_DIFFER ) { re_name( name ); } else { fprintf( stderr, _("\n[Error] File size (%.0f) of %s differs largely from that on dvd, therefore keeps it's .partial\n"), ( float ) buf.st_size, name ); } } else if( !cut_flag ) { re_name( name ); } else if( cut_flag ) { re_name( name ); } if( verbosity_level >= 1 ) { fprintf( stderr, _("[Info] Single file size (of copied file %s ) %.0f\n"), name, ( float ) buf.st_size ); fprintf( stderr, _("[Info] Cumulated size %.0f\n"), ( float ) disk_vob_size ); } } max_filesize_in_blocks_summed += max_filesize_in_blocks; fprintf( stderr, _("[Info] Successfully copied file %s\n"), name ); j++; /* # of seperate files we have written */ } /*end of main copy loop*/ if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] # of separate files: %i\n"), j ); /* * clean up and close everything */ ifoClose( vts_file ); ifoClose( vmg_file ); DVDCloseFile( dvd_file ); DVDClose( dvd ); fprintf( stderr, _("\n[Info] Copying finished! Let's see if the sizes match (roughly)\n") ); fprintf( stderr, _("[Info] Combined size of title-vobs: %.0f (%.0f MB)\n"), ( float ) vob_size, ( float ) vob_size / ( 1024*1024 ) ); fprintf( stderr, _("[Info] Copied size (size on disk): %.0f (%.0f MB)\n"), ( float ) disk_vob_size, ( float ) disk_vob_size / ( 1024*1024 ) ); if ( ( vob_size - disk_vob_size ) > MAX_DIFFER ) { fprintf( stderr, _("[Error] Hmm, the sizes differ by more than %d\n"), MAX_DIFFER ); fprintf( stderr, _("[Hint] Take a look with MPlayer if the output is ok\n") ); } else { fprintf( stderr, _("[Info] Everything seems to be fine, the sizes match pretty good ;-)\n") ); fprintf( stderr, _("[Hint] Have a lot of fun!\n") ); } return 0; } /* *this is the end of the main program, following are some useful functions * functions directly concerning the dvd have been moved to dvd.c */ /* * if you symlinked a dir to some other place the path name might not get * ended by a slash after the first tab press, therefore here is a / added * if necessary */ int add_end_slash( char *path ) { /* add a trailing '/' to path */ char *pointer; if ( path[strlen( path )-1] != '/' ) { pointer = path + strlen( path ); *pointer = '/'; pointer++; *pointer = '\0'; } return 0; } /* * get available space on target filesystem */ off_t get_free_space( char *path, int verbosity_level ) { #ifdef USE_STATFS struct statfs buf1; #else struct statvfs buf1; #endif /* ssize_t temp1, temp2; */ long temp1, temp2; off_t sum; #ifdef USE_STATFS statfs( path, &buf1 ); if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] Used the linux statfs\n") ); #else statvfs( path, &buf1 ); if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] Used statvfs\n") ); #endif temp1 = buf1.f_bavail; /* On Solaris at least, f_bsize is not the actual block size -- lb */ /* There wasn't this ifdef below, strange! How could the linux statfs * handle this since there seems to be no frsize??! */ #ifdef USE_STATFS temp2 = buf1.f_bsize; #else temp2 = buf1.f_frsize; #endif sum = ( ( off_t )temp1 * ( off_t )temp2 ); if( verbosity_level >= 1 ) { fprintf( stderr, _("[Info] In freespace_getter:for %s : %.0f free\n"), path, ( float ) sum ); fprintf( stderr, _("[Info] In freespace_getter:bavail %ld * bsize %ld = above\n"), temp1, temp2 ); } /* return ( buf1.f_bavail * buf1.f_bsize ); */ return sum; } /* * get used space on dvd (for mirroring) */ off_t get_used_space( char *path, int verbosity_level ) { #ifdef USE_STATFS struct statfs buf2; #else struct statvfs buf2; #endif /* ssize_t temp1, temp2; */ long temp1, temp2; off_t sum; #ifdef USE_STATFS statfs( path, &buf2 ); if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] Used the linux statfs\n") ); #else statvfs( path, &buf2 ); if( verbosity_level >= 1 ) fprintf( stderr, _("[Info] Used statvfs\n") ); #endif temp1 = buf2.f_blocks; /* On Solaris at least, f_bsize is not the actual block size -- lb */ /* There wasn't this ifdef below, strange! How could the linux statfs * handle this since there seems to be no frsize??! */ #ifdef USE_STATFS temp2 = buf2.f_bsize; #else temp2 = buf2.f_frsize; #endif sum = ( ( off_t )temp1 * ( off_t )temp2 ); if( verbosity_level >= 1 ) { fprintf( stderr, _("[Info] In usedspace_getter:for %s : %.0f used\n"), path, ( float ) sum ); fprintf( stderr, _("[Info] In usedspace_getter:part1 %ld, part2 %ld\n"), temp1, temp2 ); } /* return ( buf1.f_blocks * buf1.f_bsize ); */ return sum; } /* * this function concatenates the given information into a path name */ int make_output_path( char *pwd,char *name,int get_dvd_name_return, char *dvd_name,int titleid, int partcount ) { char temp[5]; strcpy( name, pwd ); strcat( name, dvd_name ); sprintf( temp, "%d", titleid ); strcat( name, temp ); if( partcount >= 0 ) { strcat( name, "-" ); sprintf( temp, "%d", partcount ); strcat( name, temp ); } strcat( name, ".vob" ); fprintf( stderr, _("\n[Info] Outputting to %s"), name ); return 0; } /* *The usage function */ void usage( char *program_name ) { fprintf( stderr, _("Vobcopy "VERSION" - GPL Copyright (c) 2001 - 2009 robos@muon.de\n") ); fprintf( stderr, _("\nUsage: %s \n"), program_name ); fprintf( stderr, _("if you want the main feature (title with most chapters) you don't need _any_ options!\n") ); fprintf( stderr, _("Options:\n") ); fprintf( stderr, _("[-m (mirror the whole dvd)] \n") ); fprintf( stderr, _("[-M (Main title - i.e. the longest (playing time) title on the dvd)] \n") ); fprintf( stderr, _("[-i /path/to/the/mounted/dvd/]\n") ); fprintf( stderr, _("[-n title-number] \n") ); fprintf( stderr, _("[-t ] \n") ); fprintf( stderr, _("[-o /path/to/output-dir/ (can be \"stdout\" or \"-\")] \n") ); fprintf( stderr, _("[-f (force output)]\n") ); fprintf( stderr, _("[-V (version)]\n") ); fprintf( stderr, _("[-v (verbose)]\n") ); fprintf( stderr, _("[-v -v (create log-file)]\n") ); fprintf( stderr, _("[-h (this here ;-)] \n") ); fprintf( stderr, _("[-I (infos about title, chapters and angles on the dvd)]\n") ); fprintf( stderr, _("[-1 /path/to/second/output/dir/] [-2 /.../third/..] [-3 /../] [-4 /../]\n") ); fprintf( stderr, _("[-b ] \n") ); fprintf( stderr, _("[-e ]\n") ); fprintf( stderr, _("[-O ] \n") ); fprintf( stderr, _("[-q (quiet)]\n") ); fprintf( stderr, _("[-w ]\n" ) ); fprintf( stderr, _("[-x (overwrite all)]\n" ) ); fprintf( stderr, _("[-F ]\n") ); #if defined( HAS_LARGEFILE ) || defined ( MAC_LARGEFILE ) fprintf( stderr, _("[-l (large-file support for files > 2GB)] \n") ); #endif exit( 1 ); } /* from play_title */ /** * Returns true if the pack is a NAV pack. This check is clearly insufficient, * and sometimes we incorrectly think that valid other packs are NAV packs. I * need to make this stronger. */ int is_nav_pack( unsigned char *buffer ) { return ( buffer[ 41 ] == 0xbf && buffer[ 1027 ] == 0xbf ); } /* *Rename: move file name from bla.partial to bla or mark as dublicate */ void re_name( char *output_file ) { char new_output_file[ 255 ]; strcpy( new_output_file, output_file ); new_output_file[ strlen( new_output_file ) - 8 ] = 0; if( ! link( output_file, new_output_file ) ) { if( unlink( output_file ) ) { fprintf( stderr, _("[Error] Could not remove old filename: %s \n"), output_file ); fprintf( stderr, _("[Hint] This: %s is a hardlink to %s. Dunno what to do... \n"), new_output_file, output_file ); } /* else fprintf( stderr, _("[Info] Removed \".partial\" from %s since it got copied in full \n"), output_file ); */ } else { if( errno == EEXIST && ! overwrite_flag ) { fprintf( stderr, _("[Error] File %s already exists! Gonna name the new one %s.dupe \n"), new_output_file, new_output_file ); strcat( new_output_file, ".dupe" ); rename( output_file, new_output_file ); } if( errno == EEXIST && overwrite_flag ) { rename( output_file, new_output_file ); } if( errno == EPERM ) /*EPERM means that the filesystem doesn't allow hardlinks, e.g. smb */ { /*this here is a stdio function which simply overwrites an existing file. Bad but I don't want to include another test...*/ rename( output_file, new_output_file ); /* fprintf( stderr, _("[Info] Removed \".partial\" from %s since it got copied in full \n"), output_file ); */ } } if( strstr( name, ".partial" ) ) name[ strlen( name ) - 8 ] = 0; } /* * Creates a directory with the given name, checking permissions and reacts accordingly (bails out or asks user) */ int makedir( char *name ) { if( mkdir( name, 0777 ) ) { if( errno == EEXIST ) { if( ! overwrite_all_flag ) { fprintf( stderr, _("[Error] The directory %s already exists!\n"), name ); fprintf( stderr, _("[Hint] You can either [c]ontinue writing to it, [x]overwrite all or you can [q]uit: ") ); } while ( 1 ) { int op; if( overwrite_all_flag == TRUE ) op = 'c'; else { while ((op = fgetc (stdin)) == EOF) usleep (1); fgetc ( stdin ); /* probably need to do this for second time it comes around this loop */ } if( op == 'c' || op == 'x' ) { if( op == 'x' ) { overwrite_all_flag = TRUE; } return 0; } else if( op == 'q' ) { exit( 1 ); } else { fprintf( stderr, _("\n[Hint] please choose [c]ontinue, [x]overwrite all or [q]uit the next time ;-)\n") ); } } } else /*most probably the user has no right to create dir or space if full or something */ { fprintf( stderr, _("[Error] Creating of directory %s\n failed! \n"), name ); fprintf( stderr, _("[Error] error: %s\n"),strerror( errno ) ); exit( 1 ); } } return 0; } /* * Check the time determine whether a new progress line should be output (once per second) */ int progressUpdate(int starttime, int cur, int tot, int force) { static int progress_time = 0; if (progress_time == 0 || progress_time != time(NULL) || force) { int barLen, barChar, numChars, timeSoFar, minsLeft, secsLeft, ctr, cols; float percentComplete, percentLeft, timePerPercent; int curtime, timeLeft; struct winsize ws; ioctl(0, TIOCGWINSZ, &ws); cols = ws.ws_col - 1; progress_time = time(NULL); curtime = time(NULL); printf("\r"); /* calc it this way so it's easy to change later */ /* 2 for brackets, 1 for space, 5 for percent complete, 1 for space, 6 for time left, 1 for space */ barLen = cols - 2 - 1 - 5 - 1 - 6 - 1; barChar = tot / barLen; percentComplete = (float)((float)cur / (float)tot * 100.0); percentLeft = 100 - percentComplete; numChars = cur / barChar; /* guess remaining time */ timeSoFar = curtime - starttime; if (percentComplete == 0) { timePerPercent = 0; } else { timePerPercent = (float)(timeSoFar / percentComplete); } timeLeft = timePerPercent * percentLeft; minsLeft = (int)(timeLeft / 60); secsLeft = (int)(timeLeft % 60); printf("["); for (ctr = 0; ctr < numChars-1; ctr++) { printf("="); } printf("|"); for (ctr = numChars; ctr < barLen; ctr++) { printf(" "); } printf("] "); printf("%5.1f%% %02d:%02d ", percentComplete, minsLeft, secsLeft); fflush(stdout); } return(0); } void install_signal_handlers() { struct sigaction action; action.sa_flags = 0; action.sa_handler = watchdog_handler; sigemptyset(&action.sa_mask); sigaction(SIGALRM, &action, NULL); action.sa_flags = 0; action.sa_handler = shutdown_handler; sigemptyset(&action.sa_mask); sigaction(SIGTERM, &action, NULL); } void watchdog_handler( int signal ) { fprintf( stderr, _("\n[Info] Timer expired - shooting myself in the head.\n") ); kill( getpid(), SIGTERM ); } void shutdown_handler( int signal ) { fprintf( stderr, _("\n[Info] Terminate signal received, exiting.\n") ); _exit( 2 ); } /* safe strcncpy, adds null terminator */ char *safestrncpy(char *dest, const char *src, size_t n) { dest[n] = '\0'; return strncpy(dest, src, n-1); } #if defined(__APPLE__) && defined(__GNUC__) || defined(OpenBSD) int fdatasync( int value ) { return 0; } #endif /* * Check the time determine whether a new progress line should be output (once per second) */ int check_progress() { static int progress_time = 0; if ( progress_time == 0 || progress_time != time(NULL) ) { progress_time = time(NULL); return( 1 ); } return( 0 ); } vobcopy-1.2.0/vobcopy.h0000644000175000017500000001163711213270553014066 0ustar robosrobos#define VERSION "1.2.0" #if defined( __gettext__ ) #include #include #define _(Text) gettext(Text) #else #define _(Text) Text #endif #define DVDCSS_VERBOSE 1 #define BLOCK_COUNT 64 #define MAX_STRING 81 #define MAX_DIFFER 2000 #include #include #include #include #include #include #include #include #include #include /*for readdir*/ #include #include #include #include #include #if ( defined( __unix__ ) || defined( unix )) && !defined( USG ) #include #endif #if defined( __GNUC__ ) && \ !( defined( sun ) ) #include #endif /* FreeBSD 4.10 and OpenBSD 3.2 has not */ /* by some bugreport:*/ #if !( defined( BSD ) && ( BSD >= 199306 ) ) && !defined( sun ) || defined(OpenBSD) #include #endif /* I'm trying to have all supported OSes definitions clearly separated here */ /* The appearance could probably be made more readable -- lb */ /* ////////// Solaris ////////// */ #if defined( __sun ) #include #include #include typedef enum { FALSE=0, TRUE=1 } bool; # if ( _FILE_OFFSET_BITS == 64 ) #define HAS_LARGEFILE 1 # endif #define off_t off64_t #else /* Solaris */ /*#define off_t __off64_t THIS HERE BREAKS OSX 10.5 */ /* ////////// *BSD ////////// */ #if ( defined( BSD ) && ( BSD >= 199306 ) ) #if !defined( __NetBSD__ ) || \ ( defined( __NetBSD__) && ( __NetBSD_Version__ < 200040000 ) ) #include #define USE_STATFS 1 #endif #if defined(__FreeBSD__) #define USE_STATFS_FOR_DEV #include #else #include #endif # if defined(NetBSD) || defined (OpenBSD) #include #define USE_GETMNTINFO # if ( __NetBSD_Version__ < 200040000 ) #include #define USE_STATFS_FOR_DEV #define GETMNTINFO_USES_STATFS # else #include #define USE_STATVFS_FOR_DEV #define GETMNTINFO_USES_STATVFS # endif #endif #if defined(__FreeBSD__) #define USE_STATFS_FOR_DEV #include #else #include #endif # if !defined(OpenBSD) #define HAS_LARGEFILE 1 #endif typedef enum { FALSE=0, TRUE=1 } bool; #else /* *BSD */ /* ////////// Darwin / OS X ////////// */ #if defined ( __APPLE__ ) /* ////////// Darwin ////////// */ # if defined( __GNUC__ ) #include #include #include /*can't be both! Should be STATVFS IMHO */ /*#define USE_STATFS 1 #define USE_STATVFS 1 #define HAS_LARGEFILE 1 */ #define GETMNTINFO_USES_STATFS 1 #define USE_GETMNTINFO 1 #define FALSE 0 #define TRUE 1 typedef int bool; # endif /* ////////// OS X ////////// */ # if defined( __MACH__ ) /* mac osx 10.5 does not seem to like this one here */ /*#include #include #include */ #define MAC_LARGEFILE 1 # endif #else /* Darwin / OS X */ /* ////////// GNU/Linux ////////// */ #if ( defined( __linux__ ) ) #include #include #include #define USE_STATFS 1 #define HAVE_GETOPT_LONG 1 #define HAS_LARGEFILE 1 typedef enum { FALSE=0, TRUE=1 } bool; #elif defined( __GLIBC__ ) #include #include #include #define HAVE_GETOPT_LONG 1 #define HAS_LARGEFILE 1 typedef enum { FALSE=0, TRUE=1 } bool; #else /* ////////// For other cases ////////// */ typedef enum { FALSE=0, TRUE=1 } bool; #if defined( __USE_FILE_OFFSET64 ) # define HAS_LARGEFILE 1 #endif #endif #endif #endif #endif /* OS/2 */ #if defined(__EMX__) #define __off64_t __int64_t #include #include #define USE_STATFS 1 #endif #include /*for/from play_title.c*/ #include /* #include "config.h" */ #include #include /* #include */ #include #include #include "dvd.h" void usage(char *); int add_end_slash( char * ); off_t get_free_space( char *, int ); off_t get_used_space( char *path, int verbosity_level ); int make_output_path( char *, char *, int, char *, int, int ); int is_nav_pack( unsigned char *buffer ); void re_name( char *output_file ); int makedir( char *name ); void install_signal_handlers(); void watchdog_handler( int signal ); void shutdown_handler( int signal ); char *safestrncpy(char *dest, const char *src, size_t n); int check_progress( void ); /* this can be removed because the one below supersedes it */ int progressUpdate( int starttime, int cur, int tot, int force ); #if defined(__APPLE__) && defined(__GNUC__) int fdatasync( int value ); #endif vobcopy-1.2.0/vobcopy.10000644000175000017500000001202411213270656013772 0ustar robosrobos.\" Process this file with .\" groff -man -Tascii vobcopy.1 .\" .TH VOBCOPY 1 "Jun 2009" Linux "User Manuals" .SH NAME vobcopy \- copy (rip) files from a dvd to the harddisk .SH SYNOPSIS .B vobcopy [-b .I size[bkmg] .B ] [-e .I size[bkmg] .B ] [-f] [-F .I fast_factor .B ] [-h] [-i .I input-dir .B ] [-l] [-m] [-M][-n .I title-number .B ] [-o .I output-dir .B ] [-q] [-O .I single_file(s)_to_rip .B ] [-t .I name .B ] [-v [-v]] [-x] [-I] [-V] [-L .I logfile-path .B ] [-1 .I aux_output_dir1 .B ] [-2 .I aux_output_dir2 .B ] [-3 .I aux_output_dir3 .B ] [-4 .I aux_output_dir4 .B ] .SH DESCRIPTION .B vobcopy copies DVD .vob files to harddisk (thanks to libdvdread) and merges them into file(s) with the name extracted from the DVD. It checks for enough free space on the destination drive and compares the copied size to the size on DVD (in case the size is wrong the files keep the .partial ending ). It should definitely work on linux and now on FreeBSD, OpenBSD, NetBSD, Solaris and MacOSX too! .BR the CSS issue: Due to possible legal issues, vobcopy doesn't include any code to descramble CSS "enhanced" DVDs. CSS is sold by the DVD industry as a "copy protection", though it's more of a "view protection" as it makes DVDs unviewable with unlicensed players. Some people have hacked CSS decryption routines, and one of those is available as a libdvdread counterpart. So if you have such a DVD, have a look at the libdvdread page. If you are positive that it's allowed where you live, you can just install that mentioned library and make decrypted backups of all your DVDs... .BR vobcopy without any options will copy the title with the most chapters into files of 2GB size into the current working directory. .SH OPTIONS .IP "-b, --begin SIZE[bkmg]" begins to copy from the specified offset-size. Modifiers like b for 512-bytes, k for kilo-bytes, m for mega- and g for giga-bytes can be appended to the number. Example: vobcopy -b 500m will start to copy from 500MB onward till the end. .IP "-e, --end SIZE[bkmg]" similar to -b, this options lets you specify some size to stop before the end. .IP "-f, --force" force the output to the specified directory even if vobcopy thinks there is not enough free space .IP "-F, --fast fast_factor" speed up the copying (experimental). fast_factor is in the range 1 to 64 .IP "-h, --help" print the command line options available .IP "-i, --input-dir INPUT-DIR" provide vobcopy with the path to the mounted dvd drive .IP "-l, --large-file" write data into one file (needs large file support (LFS)) .IP "-M, --longest" choose the title with the longest playing time. With some DVDs this gets the main title better than the most chapter method, with others it's worse. .IP "-m, --mirror" mirrors the whole dvd to harddisk. It will create a directory named after the dvd and copy the ifo, bup and vob files there. The title-vobs are decrypted during this. .IP "-n, --title-number TITLE-NUMBER" specify which title vobcopy shall copy (default is title with most chapters). On the dvd, vts_01_x.vob specify the first title (mostly this is the main feature). .IP "-o, --output-dir OUTPUT-DIR" specify the output-directory of the data. "stdout" or "-" redirect to stdout. Useful for pipeing it to /dev/null ;-) If you forget to pipe it to some place, your terminal will get garbled, so remember that typing "reset" and then Enter will rescue you. .IP "-q, --quiet" all info- and error-messages of vobcopy will end up in the current directory in vobcopy.bla instead of stderr .IP "-O, --onefile single_file(s)_to_rip" specify which single file(s) to rip. Parts of names can be given and all files which include the part will be copied. Files can be listed with comma separation. Example: -O video_ts.vob,bup will copy the single file video_ts.vob and all files containing bup .IP "-t, --name NAME" you can give the file a name if you don't like the one from dvd. -t hallo will result in hallo.vob. (stdout or "-" are deprecated now) If you want to give it names like "Huh I like this movie", do it in quotation marks. .IP "-v, --verbose" prints more information about whats going on (more verbose). .IP "-v -v" prints the information given on command line into a log-file in the current directory for inclusion into a bugreport. .IP "-x" overwrite all existing files without further questions. .IP "-L LOGFILE-PATH" tells vobcopy where to put the logfile instead of the default. .IP "-I, --info" prints information about the titles, chapters and angles on the dvd. .IP "-V, --version" prints version number. .IP "-1, --1st_alt_output_dir AUXILIARY-OUTPUT-DIR1" if the data doesn't fit on the first output-directory (specified behind -o) writing will continue here (and after -2 there and -3 and -4) -> the files will be split according to the remaining free space (try specifying the path _directly_ behind -1, _no_ space in between if you have troubles, this might be even necessary at -o...) .SH BUGS Vobcopy is still under development. So expect some. There *might* be problems for users who's system is not large-file ready. If so, please get back to me. .SH AUTHOR Robos vobcopy-1.2.0/vobcopy.1.de0000644000175000017500000001346311213270674014371 0ustar robosrobos.\" Die Datei mit .\" groff -man -Tascii vobcopy.1 .\" verarbeiten .\" .TH VOBCOPY 1 "Jun 2009" Linux "User Manuals" .SH NAME vobcopy \- kopiert (rippt) Dateien von einer (Video-) DVD auf die Festplatte .SH SYNTAX .B vobcopy [-b .I Größe[bkmg] .B ] [-e .I Größe[bkmg] .B ] [-f] [-F .I Beschleunigungsfaktor .B ] [-h] [-i .I Eingabeverzeichnis .B ] [-l] [-m] [-m][-n .I Titel-Nummer .B ] [-o .I Ausgabeverzeichnis .B ] [-q] [-O .I einzelne zu kopierende Datei .B ] [-t .I Name .B ] [-v [-v]] [-x] [-I] [-V] [-L .I Logdatei-Pfad .B ] [-1 .I zusätzliches Ausgabeverzeichnis 1 .B ] [-2 .I zusätzliches Ausgabeverzeichnis 2 .B ] [-3 .I zusätzliches Ausgabeverzeichnis 3 .B ] [-4 .I zusätzliches Ausgabeverzeichnis 4 .B ] .SH Beschreibung .B vobcopy kopiert DVD .vob-Dateien (Video-Object-Dateien) auf die Festplatte (dank libdvdread) und schreibt sie in Datei(en) mit dem Namen der DVD. Es prüft auf ausreichend freien Festplattenplatz auf der Ziel-Partition und vergleicht die kopierte Größe mit der Größe auf der DVD (für den Fall, dass die Größe falsch ist behält die Datei die Endung .partial). Es sollte auf jeden Fall auf Linux arbeiten aber auch auf *bsd und Solaris funktionieren. Mac OS X auch. .BR CSS-Angelegenheiten: Aufgrund Legalitäten enthält vobcopy keinen Code zum Entschlüsseln von um CSS "erweiterte" DVDs. CSS wird von der Filmindustrie als "Kopierschutz" angepriesen, wobei es sich eher um einen "Anschauschutz" handelt, da es DVD Material unanschaubar auf unlizensierten Abspielgeräten macht. Einige Leute haben jedoch diese CSS Entschlüsselungs-Routinen geknackt und eine dieser Routinen ist als Erweiterung zu libdvdread (siehe deren Webseite) erhältlich. .BR vobcopy Beim Aufruf ohne jegliche Optionen wird der Titel mit den meisten Kapiteln in Dateien von 2GB Größe in das aktuelle Verzeichnis kopiert. .SH OPTIONEN .IP "-b, --begin GRÖSSE[bkmg]" beginnt den Kopiervorgang erst ab der angegebenen Adresse. Die Größe der Adresse kann mit den Abkürzungen b für 512-Byte-Blöcke, k für Kilobytes, m für Mega- und g für Gigabytes angegeben werden. Beispiel: vobcopy -b 500m beginnt bei 500MB nach dem Anfang der Datei bis zum Ende zu kopieren. .IP "-e, --end GRÖSSE[bkmg]" ähnlich wie -b gibt diese Option eine Größe vor dem Ende der Datei an, an der der Kopiervorgang stoppt. .IP "-f, --force" erzwingt die Ausgabe in das angegebene Verzeichnis, auch wenn vobcopy denkt, dass dort ist nicht genügend freier Platz vorhanden ist. .IP "-F, --fast Beschleunigungsfaktor" beschleunigt das Kopieren um einen Faktor (experimentell). Der Beschleunigungsfaktor kann 1 bis 64 betragen .IP "-h, --help" Gibt die verfügbaren Optionen aus .IP "-i, --input-dir EINGABE-VERZEICHNIS" gibt das Eingabeverzeichnis an (das Verzeichnis, auf das die DVD gemountet ist). .IP "-l, --large-file" schreibt alle Daten in eine große Datei ( > 2GB, benötigt Unterstützung für große Dateien (LFS)) .IP "-M, --longest" wählt den Titel mit der längsten Spielzeit. Bei manchen DVDs wird der Hauptfilm besser gefunden als mit der Methode der meisten Kapitel, bei manchen schlechter. .IP "-m, --mirror" Spiegelt die gesamte DVD auf die Festplatte. Es wird ein Unterverzeichnis mit dem DVD-Namen erzeugt und die gesamte Dateistruktur des Videoteils wird darunter kopiert. .IP "-n, --title-number TITEL-NUMMER" gibt an, welcher Titel kopiert werden soll. Auf der DVD heißt der erste Titel vts_01_x.vob (meist der Hauptfilm). .IP "-o, --output-dir AUSGABE-VERZEICHNIS" gibt das Ausgabeverzeichnis für die Kopien an. Der Wert "stdout" oder "-" gibt auf der Standardausgabe aus. Nützlich für die Ausgabe nach /dev/null ;-) Tipp: Wenn du vergisst umzuleiten, wird dein Terminal überflutet werden, in diesem Fall tippe "reset" und Enter, um das Terminal zu retten. .IP "-q, --quiet" alle Informations- und Fehlerausschriften von vobcopy werden in die Datei vobcopy.bla im aktuellen Verzeichnis anstatt in die Standardfehlerausgabe geschrieben .IP "-O, --onefile single_file(s)_to_rip" gibt (eine) einzelne Datei(en) für das Kopieren an. Teile von Namen können angegeben werden und alle Dateien, die die Namensteile enthalten, werden kopiert. Dateinamen können als mit Komma getrennte Liste angegeben werden. Beispiel: -O video_ts.vob,bup kopiert die Datei video_ts.vob und alle Dateien, deren Namen bup enthält. .IP "-t, --name NAME" Damit kann man der Ausgabedatei einen eigenen Namen geben, wenn einem der von der DVD nicht gefällt. -t hallo erzeugt also ein hallo.vob. (stdout oder "-" sind nun nicht mehr unterstützt) Wenn du Namen mit Leerzeichen wie "Huh ich mag den Film" angeben willst, schließe den Namen in Anführungszeichen ein. .IP "-v, --verbose" schreibt noch mehr Informationen aus. .IP "-v -v" schreibt die Ausschriften in eine Logdatei im aktuellen Verzeichis um einen Fehlerreport zu erzeugen. .IP "-x" überschreibt alle existierenden Dateien ohne weitere Rückfragen. .IP "-L LOGDATEI-PFAD" weist vobcopy an die Logdatei statt in den Standardpfad in den LOGDATEI-PFAD zu legen. .IP "-I, --info" gibt Informationen über die Titel, Kapitel und Teile der DVD aus. .IP "-V, --version" gibt die Versionsnummer von vobcopy aus. .IP "-1, --1st_alt_output_dir AUXILIARY-OUTPUT-DIR1" Wenn die DVD einfach nicht in das erste Ausgabeverzeichnis passen will (mit -o angegeben), geht die Ausgabe in das hier angegebene Verzeichnis (und die folgenden 2ten, 3ten und 4ten) weiter -> die Dateien werden geteilt, je nachdem wie viel Platz in jedem der Verzeichnisse noch blieb. Gib den Pfad _direkt_ hinter "-1" an, _kein_ Leerzeichen dazwischen lassen, wenn Probleme auftreten, möglicherweise ist das auch bei -o nötig...) .SH FEHLER Vobcopy ist weiterhin unter Entwicklung, also können noch einige Neuerungen erwarten werden. Es *können* Probleme auf Systemen auftreten, die keine Unterstützung für große Dateien haben (LFS). Wenn welche auftreten, sollten diese bitte an mich gemeldet werden. .SH AUTHOR Robos vobcopy-1.2.0/vobcopy.spec0000644000175000017500000000552711213270754014575 0ustar robosrobosName: vobcopy Summary: vobcopy copies DVD .vob files to harddisk Version: 1.2.0 Release: 1 License: GPL Group: Applications/Multimedia URL: http://vobcopy.org/projects/c/c.shtml Source0: %{name}-%{version}.tar.gz Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root Requires: libdvdread BuildPrereq: libdvdread-devel %description vobcopy called without arguments will find the mounted dvd and copy the title with the most chapters to the current working directory (thats the directory you're invoking vobcopy from). It will merge together the sub-vobs of each title-vob (vts_xx_yy.vob => the xx is the title-vob, the yy and friends are the sub-vobs, mostly of 1 GB size) and copy them to harddisk in 2 GB chunks. It will get the title of the movie from the dvd and copy the data to name-of-moviexx-1.vob, name-of-moviexx-2.vob (the xx being the title number). Also possible is to mirror the whole video dvd content and single files can also be copied. %prep %setup -q %build export CFLAGS="$RPM_OPT_FLAGS" make %install rm -fr %{buildroot} install -d -m 0755 %{buildroot}/%{_bindir} install -d -m 0755 %{buildroot}/%{_mandir}/man1 install -d -m 0755 %{buildroot}/%{_mandir}/de install -d -m 0755 %{buildroot}/%{_mandir}/de/man1 install -m 0755 vobcopy %{buildroot}/%{_bindir}/ install -m 0644 vobcopy.1 %{buildroot}/%{_mandir}/man1/ install -m 0644 vobcopy.1.de %{buildroot}/%{_mandir}/de/man1/vobcopy.1 %clean rm -fr %{buildroot} %files %defattr(-,root,root) %{_bindir}/* %{_mandir}/* %doc Changelog COPYING README Release-Notes TODO alternative_programs.txt %changelog * Mon Jun 8 2009 Robos - 1.2.0: - guess what - see changelog :-) * Wed Oct 8 2008 Robos - 1.1.2: - guess what - see changelog :-) * Sun Mar 3 2008 Robos - 1.1.1: -see changelog * Sun Jan 13 2008 Robos - 1.1.0: -see changelog * Sun Jun 24 2007 Robos - 1.0.2: -see changelog * Mon Nov 13 2006 Robos - 1.0.1: -see changelog * Sun Apr 2 2006 Robos - 1.0.0: -see changelog * Wed Dez 7 2005 Robos - 0.5.16: -see changelog * Fri Jul 29 2005 Robos - 0.5.15: -option to skip already present files with -m. copying of dvd's with files ending in ";?" should work now. * Sun Oct 24 2004 Robos - 0.5.14-rc1: - misc *bsd fixes and first straight OSX support * Mon Mar 7 2004 Robos - 0.5.12-1: -m off-by-one error fixed * Mon Jan 19 2004 Robos - 0.5.10-1: -O now works cleanup * Wed Nov 13 2003 Robos - 0.5.9-1: -F now accepts factor number cleanups and small bugfix new vobcopy.spec * Sun Nov 09 2003 Florin Andrei - 0.5.8-2: libdvdread is now a pre-requisite * Sun Nov 09 2003 Florin Andrei - first package, 0.5.8-1 vobcopy-1.2.0/vobcopy.mo0000664000175000017500000004562711213270754014265 0ustar robosrobosÞ•—ÔÓŒ Ø Ù "Û þ  ;= Cy C½ `UbO¸&>/4n£»SÚ&.>UF”GÛ=#>a ¼AØS0„-¶,ä)5;"q”'°%Øþ )Q7‰+’:¾ù+0CFtB»+þ+*-V„—@¶D÷.<Lk¸ÒîV 5`k–B&E%l)’1¼1î1 1R1„1¶1è9T1k;°bìUO?¥,å_-Rà=~V¼BPV7§4ßG :\ 1— BÉ Ž !›!·!Ñ!í!"'";"N"3g"3›"Ï"Dë"$0##U#:y#.´#.ã#0$4C$x$2”$!Ç$#é$7 %7E%%}%(£%)Ì%ö%& 5&!V&+x&¤&¿&Ô&ò& '$'>')V':€'»'%Ò'ø'"(%2(X( l((­(NÍ(*%*+D*=p*N®*Qý*`O+~°+`/,T,1å,D-?\-œ-=¶-vô-3k.SŸ.\ó.dP/Mµ/O0)S0}0W›0ó0 1™1²10Ì10ý1/.2A^2# 2 Ä2,å2*3 =3^3 m3Q{3Í35Ö3G 4'T49|4=¶4Rô4LG5:”5CÏ5,6@6 U6Av6T¸66 7cD7!¨7Ê7!è7c 8An8}°8X.98‡9=À9+þ94*:4_:4”:4É:4þ:43;4h;A;ß;Eú;@<IU<tŸ<U=Qj=,¼=é=q>fy>¬à>N?qÜ?nN@I½@HA0PAMARÏAE"B]hBŽÆB#UC'yC¡C¿C$ÛCDD+'D4SDFˆDÏD>êDC)E@mEE®E/ôE2$F0WF:ˆFÃF<ÜF#G*=G9hG9¢G.ÜG H*,H$WH$|H ¡H ÂH*ãH I/I GI"hI‹I¦IÂI0ÜI: JHJ9_J™J"¶J%ÙJÿJK18K,jK’S8“UG9hK>…–‘s+2‡-0~4gfˆ}B‚yELH?wd]q€C†.F&iR(VkA) uDlm 7O”NjX,_o5;M`{e#!QŠJ„ŽvTY1 n—\z<6b‰=^tŒ :|‹IZ rx@ƒc[$*/p%3W•Pa '" [Error] Bloody path to long '%s' [Error] Error opening file %s [Error] Error writing to %s [Error] File '%s' already exists, [o]verwrite or [q]uit? [Error] File '%s' already exists, [o]verwrite, [a]ppend, [q]uit? [Error] File '%s' already exists, [o]verwrite, [s]kip or [q]uit? [Error] File size (%.0f) of %s differs largely from that on dvd, therefore keeps it's .partial [Error] Hmm, better change to a dir with enough space left or call with -f (force) [Error] Hmm, the path length of your current directory is really large (>255) [Error] Path thingy didn't work '%s' [Error] Something went wrong during the size detection of the [Error] There can be only one: either -m or -n...' [Error] Write() error [Error] error writing to %s [Error] vobs, size check at the end won't work (probably), but I continue anyway [Hint] File on dvd ends in ";?" (%s) [Hint] Please choose [o]verwrite or [q]uit the next time ;-) [Hint] Please choose [o]verwrite, [a]ppend, [q]uit the next time ;-) [Hint] Please choose [o]verwrite, [s]kip, or [q]uit the next time ;-) [Hint] please choose [c]ontinue or [q]uit the next time ;-) [Hint] please choose [o]verwrite or [q]uit the next time ;-) [Info] Disk free: %.0f MB [Info] Vobs size: %.0f MB [Info] Copying finished! Let's see if the sizes match (roughly) [Info] DVD-name: %s [Info] Difference between vobsize read from cd and size returned from libdvdread: [Info] Outputting to %s [Info] Path to dvd: %s [Info] Setting watchdog timer to %d minutes [Info] Terminate signal received, exiting. [Info] There are %d angles on this dvd. [Info] Timer expired - shooting myself in the head. [Info] Your-name for the dvd: %s %4.0fMB of %4.0fMB written %4.0fMB of %4.0fMB written ( 100.0 %%) %4.0fMB of %4.0fMB written (%.0f %%) %4.0fkB of %4.0fkB written ( %3.1f %% ) ( 100.0%% ) -------------------------------------------------------------------------------- Vobcopy [-l (large-file support for files > 2GB)] [Error] %s was compiled without support for long options. [Error] Can't open VMG info. [Error] Can't open the title %d info file. [Error] Can't open title VOBS (VTS_%02d_1.VOB). [Error] Could not get the device and path! Maybe not mounted the dvd? [Error] Could not get the device which belongs to the given path! [Error] Could not remove old filename: %s [Error] Creating of directory %s failed! [Error] Erm, the number comes behind -n ... [Error] Error: %s [Error] Error: %s, errno: %d [Error] File %s already exists! Gonna name the new one %s.dupe [Error] Hmm, statfs (statvfs) seems not to work on that directory. [Error] Hmm, the sizes differ by more than %d [Error] Hmm, weird, the dir video_ts|VIDEO_TS on the dvd couldn't be opened [Error] Invalid angle %d [Error] Invalid chapter %d [Error] Invalid title %d. [Error] Not enough free space on the destination dir. Please choose another one or -f [Error] Please choose [y] to continue or [n] to quit [Error] Please don't use -i /dev/something in this version, only the next version will support this again. [Error] Please specify output dirs in this order: -o -1 -2 -3 -4 [Error] Seems your platter is full... [Error] The dir to be opened was: %s [Error] The directory %s already exists! [Error] The thing behind -F has to be a number! [Error] The thing behind -a has to be a number! [Error] The thing behind -b has to be a number! [Error] The thing behind -c has to be a number! [Error] The thing behind -e has to be a number! [Error] The thing behind -n has to be a number! [Error] The thing behind -w has to be a number! [Error] Try something like -i /cdrom, /dvd or /mnt/dvd [Error] Wrong option. [Error] Wrong suffix behind -b, only b,k,m or g [Error] error: %s [Error] or dirs behind -1, -2 ... are NOT allowed with -m! [Hint] All lines starting with "libdvdread:" are not from vobcopy but from the libdvdread-library [Hint] By the way, you have %i cdroms|dvds mounted, that probably caused the problem [Hint] Change to a path with shorter path length pleeeease ;-) [Hint] Erm, the number comes behind -n ... [Hint] Have a lot of fun! [Hint] If vobcopy makes trouble, please mail me so that I can fix this (robos@muon.de). Thanks [Hint] If you don't like that position, use -L /path/to/logfile/ instead of -v -v [Hint] Make sure that vobcopy doesn't have to ask questions (like overwriting of old files), these questions end up in the log file so you don't see them... [Hint] Negative minutes aren't allowed - disabling watchdog. [Hint] Nevertheless, do you want vobcopy to continue [y] or do you want to check for [Hint] Please mail me what your vobcopy call plus -v -v spits out [Hint] Please use the mount point instead (/cdrom, /dvd, /mnt/dvd or something) [Hint] Quiet mode - All messages will now end up in %s [Hint] Take a look with MPlayer if the output is ok [Hint] The largest value for -F is %d at the moment - used that one... [Hint] This: %s is a hardlink to %s. Dunno what to do... [Hint] Um, you set angle to 0, try 1 instead ;-) [Hint] You can either [c]ontinue writing to it or you can [q]uit: [Hint] You use -i. Normally this is not necessary, vobcopy finds the input dir by itself. This option is only there if vobcopy makes trouble. [Info] Disk free: %.0f MB [Info] Disk free: %f MB [Info] Vobs size: %.0f MB [Info] Vobs size: %f MB [Info] # of separate files: %i [Info] All titles: [Info] Called: %s [Info] Can't stat() %s. [Info] Combined size of title-vobs: %.0f (%.0f MB) [Info] Copied size (size on disk): %.0f (%.0f MB) [Info] Cumulated size %.0f [Info] Everything seems to be fine, the sizes match pretty good ;-) [Info] Free space for -%i dir: %.0f [Info] Free space for -o dir: %.0f [Info] In freespace_getter:bavail %ld * bsize %ld = above [Info] In freespace_getter:for %s : %.0f free [Info] In usedspace_getter:for %s : %.0f used [Info] In usedspace_getter:part1 %ld, part2 %ld [Info] Most chapters has title %i with %d chapters. [Info] Name of the dvd: %s [Info] Single file size (of copied file %s ) %.0f [Info] Start of %s at %d blocks [Info] Successfully copied file %s [Info] Taken max_filesize_in_blocks(2GB version): %.0f [Info] Taken max_filesize_in_blocks(lfs version): %.0f [Info] The log-file is written to %s [Info] There are %d titles on this DVD. [Info] There are %i chapters on the dvd. [Info] Title %i has %d angle. [Info] Title %i has %d angles. [Info] Title %i has %d chapter. [Info] Title %i has %d chapters. [Info] Title has %d chapters and %d angles [Info] Uhu, super-verbose [Info] Used statvfs [Info] Used the linux statfs [Info] User chose append [Info] Using Angle: %i [Info] Using Chapter: %i [Info] Using Title: %i [Info] Vob %d %d (%s) has a size of %lli [Info] Vob_size (stat) = %lu [Info] libdvdsize = %lu [Info] Vob_size was 0 [Info] Writing files to this dir: %s [Info] Writing to %s [Info] file_size_in_blocks %8.0f [Info] max_filesize_in_blocks %8.0f [Info] n/q pressed [Info] offset at the end %8.0f [Info] y pressed - force write [Warn] Had to skip %d blocks! Project-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2008-03-31 23:48+0200 PO-Revision-Date: 2008-03-31 23:49+0200 Last-Translator: robos Language-Team: German MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); [Fehler] Der Pfad ist zu lang! '%s' [Fehler] Fehler beim OEffnen der Datei %s [Fehler] Es sind Fehler aufgetreten beim Schreiben nach %s [Fehler] Datei '%s' existiert bereits, [o]ueberschreiben oder [q]aufhoeren? [Fehler] Datei '%s' gibt es schon, [o]ueberschreiben, [a]nhaengen, [q]beenden? [Fehler] Datei '%s' existiert bereits, [o]ueberschreiben, [s]ueberspringen oder [q]aufhoeren? [Fehler] Die Dateigroesse (%.0f) von %s unterscheidet sich zu sehr von der der DVD, deshalb behaehlt sie die Endung .partial [Fehler] Hmm, wechsle besser in ein Verzeichnis mit genug freiem Platz oder benutze -f (force) [Fehler] Hmm, Die Anzahl der Buchstaben des aktuellen Pfades ist echt gross (>255) [Fehler] Pfad-Suche hat nicht funktioniert '%s' [Fehler] Irgendwas ist schiefgelaufen bei der Groessenerkennung der [Fehler] Man kann nur eines benutzen: entweder -m oder -n...' [Fehler] Write() Fehler [Fehler] Es sind Fehler aufgetreten beim Schreiben nach %s [Fehler] Vobs, der Groessenvergleich am Ende wird (wahrscheinlich) nicht funktionieren aber ich fahre trotzdem fort [Hinweis] Dateien auf der DVD enden auf ";?" (%s) [Hinweis] Bitte waehle [o]ueberschreiben oder [q]aufhoeren das naechste Mail ;-) [Hinweis] Bitte waehle [o]ueberschreiben, [a]nhaengen oder [q]beenden das naechste Mal ;-) [Hinweis] Bitte waehle [o]ueberschreiben, [s]ueberspringen oder [q]aufhoeren? das naechste Mal ;-) [Hinweis] Bitte waehle [c]weitermachen oder [q]stoppen das naechste Mal ;-) [Hinweis] Bitte waehle [o]ueberschreiben oder [q]beenden das naechste Mal ;-) [Info] Freier Festplattenplatz: %.0f MB [Info] VOB Groesse: %.0f MB [Info] Das Kopieren wurde beendet! Nun schauen wir mal ob die Groessen stimmen (grob) [Info] DVD-Name: %s [Info] Es gibt eine Differenz zwischen der Groesse der VOBs ermittelt von der DVD und der Groesse zurueckgegeben von derlibdvdread Bibliothek [Info] Schreibe nach %s [Info] Pfad zur dvd: %s [Info] Setze den Watchdog Timer auf %d Minuten [Info] Beende-Signal erhalten, beende vobcopy. [Info] Es gibt %d Blickwinkel auf dieser DVD. [Info] Der Watchdog-Timer ist abgelaufen - schiesse vobcopy ab. [Info] Dein Name fuer die DVD: %s %4.0fMB von %4.0fMB geschrieben %4.0fMB von %4.0fMB geschrieben ( 100.0 %%) %4.0fMB von %4.0fMB geschrieben (%.0f %%) %4.0fkB von %4.0fkB geschrieben ( %3.1f %% ) ( 100.0%% ) -------------------------------------------------------------------------------- Vobcopy [-l (large-file Unterstuetzung fuer Dateien > 2GB)] [Fehler] %s wurde ohne Unterstuetzung fuer lange Optionen kompiliert. [Fehler] Kann VMG Info nicht oeffnen. [Fehler] Kann vom Titel %d die Info-Datei nicht oeffnen. [Fehler] Kann die Titel-VOBs nicht oeffnen (VTS_%02d_1.VOB). [Fehler] Konnte weder das Device noch den Pfad ermitteln! Ist eine DVD gemountet? [Fehler] Das Device das zu dem Pfad gehoert konnte nicht ermittelt werden! [Fehler] Konnte den alten Dateinamen nicht entfernen: %s [Fehler] Das Erstellen des Verzeichnisses %s ist fehlgeschlagen! [Fehler] Erm, die Zahl kommt hinter -n ... [Fehler] Fehler: %s [Fehler] Fehler: %s, errno: %d [Fehler] Die Datei %s gibts schon! Werde die neue %s.dupe nennen [Fehler] Hmm, statfs (statvfs) scheint bei dem Verzeichnis nicht zu funktionieren. [Fehler] Hmm, die Groessen differieren um mehr als %d [Fehler] Hmm, komisch, das Verzeichnis video_ts|VIDEO_TS auf der DVD konnte nicht geoeffnet werden [Fehler] Falscher Blickwinkel %d [Fehler] Falsches Kapitel %d [Fehler] Fehlerhafter Titel %d. [Fehler] Am Zielort ist nicht genug Platz vorhanden. Bitte waehle einen anderen Ortoder benutze -f [Fehler] Bitte waehle [y] um weiterzumachen oder [n] zum stoppen [Fehler] Bitte benute nicht -i /dev/irgendwas in dieser Version, eine der naechstenVersionen wird dies wieder unterstuetzen. [Fehler] Bitte spezifiziere die Ausgabeverzeichnisse in dieser Abfolge: -o -1 -2 -3 -4 [Fehler] Sieht so aus als waere die Festplatte voll ... [Fehler] Das Verzeichnis das geoeffnet werden sollte war: %s [Fehler] Das Verzeichnis %s gibt es schon! [Fehler] Die Angabe hinter -F muss eine Zahl sein! [Fehler] Die Angabe hinter -a muss eine Zahl sein! [Fehler] Die Angabe hinter -b muss eine Zahl sein! [Fehler] Die Angabe hinter -c muss eine Zahl sein! [Fehler] Die Angabe hinter -e muss eine Zahl sein! [Fehler] Die Angabe hinter -n muss eine Zahl sein! [Fehler] Die Angabe hinter -w muss eine Zahl sein! [Fehler] Versuche bitte etwas wie -i /cdrom, /dvd oder /mnt/dvd [Fehler] Falsche Option. [Fehler] Falscher Suffix hinter -b, nur b, k, m oder g sind erlaubt [Fehler] Fehler: %s [Fehler] oder Verzeichnisse hinter -1, -2 ... sind NICHT erlaubt bei -m! [Hinweis] Alle Zeilen die mit "libdvdread:" beginnen sind nicht von vobcopy sondern von der libdvdread-Bibliothek. [Hinweis] Nebenbei, du hast %i cdroms/dvds gemountet, vielleicht ist das das Problem [Hinweis] Wechsle bitte in ein Verzeichnis muss weniger Buchstaben, bitte?! ;-) [Hinweis] Erm, die Zahl kommt hinter -n ... [Hinweis] Have a lot of fun! [Hinweis] Sollte vobcopy Probleme betreiten, bitte maile mir so das ich das beheben kann/robos@muon.de). Danke! [Hinweis] Wenn dir die Position nicht gefaellt, benutze -L /pfad/zur/Logdatei stattdessen oder -v -v [Hinweis] Pass auf das vobcopy keine Fragen stellen muss (wie z.B. ob alte Dateien ueberschrieben werden sollen), diese enden auch im Logfile wo dusie nicht sehen wirst... [Hinweis] Negative Zeitangaben sind nicht erlaubt - schalte den Watchdog ab. [Hinweis] Nichtdestotrotz, soll vobcopy weitermachen [y] oder willst du vorher den freien Platzueberpruefen [q]? [Hinweis] Bitte sende mir eine Email mit der Ausgabe deines Vobcopy-Aufrufs plus zusaetzlich die -v -v Option [Hinweis] Bitte benutze den Mountpunkt (/cdrom, /dvd, /mnt/dvd oder so) [Hinweis] Leise-Modus - Alle Nachrichten werden jetzt nach %s geleitet [Hinweis] Schau mit MPlayer ob die Kopie ok ist [Hinweis] Der groesste Wert fuer -F ist %d im Moment - benutze diesen nun... [Hinweis] Dier hier: %s ist ein Hardlink auf %s. Weiss nicht was ich tun soll... [Hint] Um, du hast den Winkel auf 0 gesetzt, nehme 1 stattdessen ;-) [Hinweis] Du kannst entweder [c]weitermachen dorthin zu schreiben oder du kannst [q]stoppen: [Hinweis] Du benutzt -i. Dies ist normalerweise nicht notwendig, vobcopy findet die Quelle selbst. Die Option ist nur fuer Problemfaelle da. [Info] Plattenplatz frei: %.0f MB [Info] Freier Festplattenplatz: %f MB [Info] Vob Groesse: %.0f MB [Info] Vob Groesse: %f MB [Info] Anzahl separater Dateien: %i [Info] Alle Titel: [Info] Aufruf: %s [Info] Kann stat() nicht aufrufen fuer %s. [Info] Gesamtgroesse der Titel-VOBs: %.0f (%.0f MB) [Info] Kopierte Groesse (Groesse auf der Festplatte): %.0f (%.0f MB) [Info] Gesamtgroesse %.0f [Info] Alles sieht gut aus, die Groessen passen recht gut ;-) [Info] Freier Festplattenspeicher fuer das -%ite Verzeichnis: %.0f [Info] Freier Festplattenspeicher fuer das -o Verzeichnis: %.0f [Info] In freespace_getter:bavail %ld * bsize %ld = das hier drueber [Info] In freespace_getter:fuer %s : %.0f frei [Info] In usedspace_getter:fuer %s : %.0f benutzt [Info] In usedspace_getter:part1 %ld, part2 %ld [Info] Die meisten Kapitel hat Titel %i mit %d Kapiteln. [Info] Name der DVD: %s [Info] Einzelne Dateigroesse (der kopierten Datei %s ) %.0f [Info] Start von %s bei %d blocks [Info] Datei wurde erfolgreich kopiert %s [Info] Benutze max_filesize_in_blocks(2GB Version): %.0f [Info] Benutze max_filesize_in_blocks(lfs Version): %.0f [Info] Die Log-Datei wird nach %s geschieben [Info] Diese DVD hat %d Titel. [Info] Es sind %i Kapitel auf dieser DVD. [Info] Titel %i hat %d Blickwinkel. [Info] Titel %i hat %d Blickwinkel. [Info] Titel %i hat %d Kapitel. [Info] Titel %i hat %d Kapitel. [Info] Titel hat %d Kapitel und %d Winkel [Info] Hui, super-ausfuehrlich [Info] Benutze statvfs [Info] Benutze das linux statfs [Info] Benutzer waehlte anhaengen [Info] Benutze Winkel: %i [Info] Benutze Kapitel: %i [Info] Benutze Titel: %i [Info] Vob %d %d (%s) hat eine Groesse von %lli [Info] Vob_size (stat) = %lu [Info] libdvdsize = %lu [Info] Vob_size war 0 [Info] Schreibe die Dateien in folgendes Verzeichnis: %s [Hinweis] Schreibe nach %s [Info] file_size_in_blocks %8.0f [Info] max_filesize_in_blocks %8.0f [Info] n/q wurde gewaehlt [Info] Offset am Ende %8.0f [Info] y wurde gewaehlt - erzwinge das Schreiben [Warnung] Musste %d Bloecke ueberspringen! vobcopy-1.2.0/vobcopy.pot0000644000175000017500000003751011213270754014442 0ustar robosrobos# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-03-31 23:48+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: vobcopy.c:189 #, c-format msgid "[Error] The thing behind -a has to be a number! \n" msgstr "" #: vobcopy.c:196 #, c-format msgid "[Hint] Um, you set angle to 0, try 1 instead ;-)\n" msgstr "" #: vobcopy.c:204 #, c-format msgid "[Error] The thing behind -b has to be a number! \n" msgstr "" #: vobcopy.c:211 vobcopy.c:234 vobcopy.c:265 vobcopy.c:287 #, c-format msgid "[Error] Wrong suffix behind -b, only b,k,m or g \n" msgstr "" #: vobcopy.c:248 #, c-format msgid "[Error] The thing behind -c has to be a number! \n" msgstr "" #: vobcopy.c:258 #, c-format msgid "[Error] The thing behind -e has to be a number! \n" msgstr "" #: vobcopy.c:310 #, c-format msgid "[Error] Erm, the number comes behind -n ... \n" msgstr "" #: vobcopy.c:313 #, c-format msgid "" "[Hint] You use -i. Normally this is not necessary, vobcopy finds the input " "dir by itself. This option is only there if vobcopy makes trouble.\n" msgstr "" #: vobcopy.c:314 #, c-format msgid "" "[Hint] If vobcopy makes trouble, please mail me so that I can fix this " "(robos@muon.de). Thanks\n" msgstr "" #: vobcopy.c:318 #, c-format msgid "" "[Error] Please don't use -i /dev/something in this version, only the next " "version will support this again.\n" msgstr "" #: vobcopy.c:319 #, c-format msgid "" "[Hint] Please use the mount point instead (/cdrom, /dvd, /mnt/dvd or " "something)\n" msgstr "" #: vobcopy.c:340 #, c-format msgid "[Error] The thing behind -n has to be a number! \n" msgstr "" #: vobcopy.c:350 vobcopy.c:382 #, c-format msgid "[Hint] Erm, the number comes behind -n ... \n" msgstr "" #: vobcopy.c:376 #, c-format msgid "[Error] Please specify output dirs in this order: -o -1 -2 -3 -4 \n" msgstr "" #: vobcopy.c:410 #, c-format msgid "[Error] The thing behind -F has to be a number! \n" msgstr "" #: vobcopy.c:416 #, c-format msgid "" "[Hint] The largest value for -F is %d at the moment - used that one...\n" msgstr "" #: vobcopy.c:427 #, c-format msgid "[Error] The thing behind -w has to be a number! \n" msgstr "" #: vobcopy.c:433 #, c-format msgid "[Hint] Negative minutes aren't allowed - disabling watchdog.\n" msgstr "" #: vobcopy.c:479 vobcopy.c:493 #, c-format msgid "[Error] Wrong option.\n" msgstr "" #: vobcopy.c:486 #, c-format msgid "[Error] %s was compiled without support for long options.\n" msgstr "" #: vobcopy.c:499 vobcopy.c:2022 #, c-format msgid "Vobcopy " msgstr "" #: vobcopy.c:500 #, c-format msgid "" "[Hint] All lines starting with \"libdvdread:\" are not from vobcopy but from " "the libdvdread-library\n" msgstr "" #: vobcopy.c:511 #, c-format msgid "" "\n" "[Error] Hmm, the path length of your current directory is really large " "(>255)\n" msgstr "" #: vobcopy.c:512 #, c-format msgid "[Hint] Change to a path with shorter path length pleeeease ;-)\n" msgstr "" #: vobcopy.c:526 #, c-format msgid "[Hint] Quiet mode - All messages will now end up in %s\n" msgstr "" #: vobcopy.c:575 #, c-format msgid "[Info] Uhu, super-verbose\n" msgstr "" #: vobcopy.c:615 #, c-format msgid "[Info] The log-file is written to %s\n" msgstr "" #: vobcopy.c:616 #, c-format msgid "" "[Hint] Make sure that vobcopy doesn't have to ask questions (like " "overwriting of old files), these questions end up in the log file so you " "don't see them...\n" msgstr "" #: vobcopy.c:617 #, c-format msgid "" "[Hint] If you don't like that position, use -L /path/to/logfile/ instead of -" "v -v\n" msgstr "" #: vobcopy.c:633 #, c-format msgid "--------------------------------------------------------------------------------\n" msgstr "" #: vobcopy.c:634 #, c-format msgid "[Info] Called: %s\n" msgstr "" #: vobcopy.c:640 #, c-format msgid "" "\n" "[Error] There can be only one: either -m or -n...'\n" msgstr "" #: vobcopy.c:653 #, c-format msgid "" "\n" "[Error] Bloody path to long '%s'\n" msgstr "" #: vobcopy.c:665 #, c-format msgid "[Error] Could not get the device which belongs to the given path!\n" msgstr "" #: vobcopy.c:678 #, c-format msgid "[Error] Could not get the device and path! Maybe not mounted the dvd?\n" msgstr "" #: vobcopy.c:688 #, c-format msgid "" "\n" "[Info] Path to dvd: %s\n" msgstr "" #: vobcopy.c:692 #, c-format msgid "" "\n" "[Error] Path thingy didn't work '%s'\n" msgstr "" #: vobcopy.c:693 #, c-format msgid "[Error] Try something like -i /cdrom, /dvd or /mnt/dvd \n" msgstr "" #: vobcopy.c:695 #, c-format msgid "" "[Hint] By the way, you have %i cdroms|dvds mounted, that probably caused the " "problem\n" msgstr "" #: vobcopy.c:706 #, c-format msgid "[Info] Name of the dvd: %s\n" msgstr "" #: vobcopy.c:722 #, c-format msgid "[Error] Can't open VMG info.\n" msgstr "" #: vobcopy.c:754 #, c-format msgid "[Info] There are %d titles on this DVD.\n" msgstr "" #: vobcopy.c:758 #, c-format msgid "[Error] Invalid title %d.\n" msgstr "" #: vobcopy.c:769 #, c-format msgid "[Info] There are %i chapters on the dvd.\n" msgstr "" #: vobcopy.c:770 #, c-format msgid "[Info] Most chapters has title %i with %d chapters.\n" msgstr "" #: vobcopy.c:775 vobcopy.c:818 #, c-format msgid "[Info] All titles:\n" msgstr "" #: vobcopy.c:780 #, c-format msgid "[Info] Title %i has %d chapters.\n" msgstr "" #: vobcopy.c:783 #, c-format msgid "[Info] Title %i has %d chapter.\n" msgstr "" #: vobcopy.c:793 #, c-format msgid "[Error] Invalid chapter %d\n" msgstr "" #: vobcopy.c:807 #, c-format msgid "" "\n" "[Info] There are %d angles on this dvd.\n" msgstr "" #: vobcopy.c:810 #, c-format msgid "[Error] Invalid angle %d\n" msgstr "" #: vobcopy.c:823 #, c-format msgid "[Info] Title %i has %d angles.\n" msgstr "" #: vobcopy.c:826 #, c-format msgid "[Info] Title %i has %d angle.\n" msgstr "" #: vobcopy.c:844 #, c-format msgid "" "\n" "[Error] Something went wrong during the size detection of the" msgstr "" #: vobcopy.c:845 #, c-format msgid "" "\n" "[Error] vobs, size check at the end won't work (probably), but I continue " "anyway\n" "\n" msgstr "" #: vobcopy.c:874 #, c-format msgid "" "\n" "[Info] Setting watchdog timer to %d minutes\n" msgstr "" #: vobcopy.c:884 vobcopy.c:1364 vobcopy.c:1444 vobcopy.c:1514 #, c-format msgid "" "\n" "[Info] DVD-name: %s\n" msgstr "" #: vobcopy.c:885 vobcopy.c:1445 #, c-format msgid "[Info] Disk free: %.0f MB\n" msgstr "" #: vobcopy.c:886 vobcopy.c:1447 #, c-format msgid "[Info] Vobs size: %.0f MB\n" msgstr "" #: vobcopy.c:911 #, c-format msgid "[Info] Writing files to this dir: %s\n" msgstr "" #: vobcopy.c:924 #, c-format msgid "" "[Error] Hmm, weird, the dir video_ts|VIDEO_TS on the dvd couldn't be opened\n" msgstr "" #: vobcopy.c:925 #, c-format msgid "[Error] The dir to be opened was: %s\n" msgstr "" #: vobcopy.c:926 #, c-format msgid "[Hint] Please mail me what your vobcopy call plus -v -v spits out\n" msgstr "" #: vobcopy.c:1001 #, c-format msgid "" "\n" "[Hint] File on dvd ends in \";?\" (%s)\n" msgstr "" #: vobcopy.c:1009 #, c-format msgid "[Info] Writing to %s \n" msgstr "" #: vobcopy.c:1014 #, c-format msgid "" "\n" "[Error] File '%s' already exists, [o]verwrite, [s]kip or [q]uit? " msgstr "" #: vobcopy.c:1026 vobcopy.c:1071 vobcopy.c:1097 vobcopy.c:1610 vobcopy.c:1661 #: vobcopy.c:1677 vobcopy.c:1707 #, c-format msgid "" "\n" "[Error] Error opening file %s\n" msgstr "" #: vobcopy.c:1027 vobcopy.c:1072 vobcopy.c:1098 vobcopy.c:1141 vobcopy.c:1176 #: vobcopy.c:1611 vobcopy.c:1750 #, c-format msgid "[Error] Error: %s\n" msgstr "" #: vobcopy.c:1048 #, c-format msgid "" "\n" "[Hint] Please choose [o]verwrite, [s]kip, or [q]uit the next time ;-)\n" msgstr "" #: vobcopy.c:1059 vobcopy.c:1599 #, c-format msgid "" "\n" "[Error] File '%s' already exists, [o]verwrite or [q]uit? \n" msgstr "" #: vobcopy.c:1088 #, c-format msgid "" "\n" "[Hint] Please choose [o]verwrite or [q]uit the next time ;-)\n" msgstr "" #: vobcopy.c:1140 vobcopy.c:1175 vobcopy.c:1287 #, c-format msgid "" "\n" "[Error] Error writing to %s \n" msgstr "" #: vobcopy.c:1146 vobcopy.c:1181 #, c-format msgid "%4.0fkB of %4.0fkB written\r" msgstr "" #: vobcopy.c:1149 vobcopy.c:1184 vobcopy.c:1317 vobcopy.c:1720 #, c-format msgid "\n" msgstr "" #: vobcopy.c:1154 vobcopy.c:1189 vobcopy.c:1322 vobcopy.c:1773 #, c-format msgid "" "\n" "[Error] error writing to %s \n" msgstr "" #: vobcopy.c:1155 vobcopy.c:1190 vobcopy.c:1323 vobcopy.c:1774 vobcopy.c:2144 #, c-format msgid "[Error] error: %s\n" msgstr "" #: vobcopy.c:1237 #, c-format msgid "[Info] Can't stat() %s.\n" msgstr "" #: vobcopy.c:1243 #, c-format msgid "[Info] Vob %d %d (%s) has a size of %lli\n" msgstr "" #: vobcopy.c:1257 #, c-format msgid "[Info] Start of %s at %d blocks \n" msgstr "" #: vobcopy.c:1279 #, c-format msgid "[Warn] Had to skip %d blocks! " msgstr "" #: vobcopy.c:1288 #, c-format msgid "[Error] Error: %s, errno: %d \n" msgstr "" #: vobcopy.c:1301 vobcopy.c:1311 #, c-format msgid "%4.0fMB of %4.0fMB written " msgstr "" #: vobcopy.c:1304 #, c-format msgid "( %3.1f %% ) \r" msgstr "" #: vobcopy.c:1314 #, c-format msgid "( 100.0%% ) \r" msgstr "" #: vobcopy.c:1340 #, c-format msgid "" "[Error] Not enough free space on the destination dir. Please choose another " "one or -f\n" msgstr "" #: vobcopy.c:1341 #, c-format msgid "[Error] or dirs behind -1, -2 ... are NOT allowed with -m!\n" msgstr "" #: vobcopy.c:1356 #, c-format msgid "[Info] Using Title: %i\n" msgstr "" #: vobcopy.c:1357 #, c-format msgid "[Info] Title has %d chapters and %d angles\n" msgstr "" #: vobcopy.c:1358 #, c-format msgid "[Info] Using Chapter: %i\n" msgstr "" #: vobcopy.c:1359 #, c-format msgid "[Info] Using Angle: %i\n" msgstr "" #: vobcopy.c:1365 #, c-format msgid "[Info] Disk free: %f MB\n" msgstr "" #: vobcopy.c:1366 #, c-format msgid "[Info] Vobs size: %f MB\n" msgstr "" #: vobcopy.c:1381 #, c-format msgid "[Error] Can't open the title %d info file.\n" msgstr "" #: vobcopy.c:1408 #, c-format msgid "[Error] Can't open title VOBS (VTS_%02d_1.VOB).\n" msgstr "" #: vobcopy.c:1425 #, c-format msgid "[Info] Vob_size was 0\n" msgstr "" #: vobcopy.c:1432 #, c-format msgid "" "\n" "[Info] Difference between vobsize read from cd and size returned from " "libdvdread:\n" msgstr "" #: vobcopy.c:1437 #, c-format msgid "" "[Info] Vob_size (stat) = %lu\n" "[Info] libdvdsize = %lu\n" msgstr "" #: vobcopy.c:1461 #, c-format msgid "" "\n" "[Info] Disk free: %.0f MB" msgstr "" #: vobcopy.c:1462 #, c-format msgid "" "\n" "[Info] Vobs size: %.0f MB" msgstr "" #: vobcopy.c:1464 #, c-format msgid "" "\n" "[Error] Hmm, better change to a dir with enough space left or call with -f " "(force) \n" msgstr "" #: vobcopy.c:1468 vobcopy.c:1469 #, c-format msgid "[Error] Hmm, statfs (statvfs) seems not to work on that directory. \n" msgstr "" #: vobcopy.c:1470 #, c-format msgid "" "[Hint] Nevertheless, do you want vobcopy to continue [y] or do you want to " "check for \n" msgstr "" #: vobcopy.c:1471 #, c-format msgid "[Hint] enough space first [q]?\n" msgstr "" #: vobcopy.c:1481 #, c-format msgid "[Info] y pressed - force write\n" msgstr "" #: vobcopy.c:1487 #, c-format msgid "[Info] n/q pressed\n" msgstr "" #: vobcopy.c:1493 #, c-format msgid "[Error] Please choose [y] to continue or [n] to quit\n" msgstr "" #: vobcopy.c:1518 #, c-format msgid "" "\n" "[Info] Your-name for the dvd: %s\n" msgstr "" #: vobcopy.c:1534 #, c-format msgid "[Info] Free space for -o dir: %.0f\n" msgstr "" #: vobcopy.c:1563 #, c-format msgid "[Info] Free space for -%i dir: %.0f\n" msgstr "" #: vobcopy.c:1579 #, c-format msgid "[Info] Taken max_filesize_in_blocks(2GB version): %.0f\n" msgstr "" #: vobcopy.c:1587 #, c-format msgid "[Info] Taken max_filesize_in_blocks(lfs version): %.0f\n" msgstr "" #: vobcopy.c:1627 #, c-format msgid "" "\n" "[Hint] please choose [o]verwrite or [q]uit the next time ;-)\n" msgstr "" #: vobcopy.c:1643 #, c-format msgid "[Error] Seems your platter is full...\n" msgstr "" #: vobcopy.c:1646 #, c-format msgid "" "\n" "[Error] File '%s' already exists, [o]verwrite, [a]ppend, [q]uit? \n" msgstr "" #: vobcopy.c:1683 #, c-format msgid "[Info] User chose append\n" msgstr "" #: vobcopy.c:1694 #, c-format msgid "" "\n" "[Hint] Please choose [o]verwrite, [a]ppend, [q]uit the next time ;-)\n" msgstr "" #: vobcopy.c:1746 #, c-format msgid "" "\n" "[Error] Write() error\n" msgstr "" #: vobcopy.c:1762 #, c-format msgid "%4.0fMB of %4.0fMB written (%.0f %%)\r" msgstr "" #: vobcopy.c:1778 #, c-format msgid "%4.0fMB of %4.0fMB written ( 100.0 %%)\r" msgstr "" #: vobcopy.c:1786 #, c-format msgid "[Info] max_filesize_in_blocks %8.0f \n" msgstr "" #: vobcopy.c:1787 #, c-format msgid "[Info] offset at the end %8.0f \n" msgstr "" #: vobcopy.c:1788 #, c-format msgid "[Info] file_size_in_blocks %8.0f \n" msgstr "" #: vobcopy.c:1803 #, c-format msgid "" "\n" "[Error] File size (%.0f) of %s differs largely from that on dvd, therefore " "keeps it's .partial\n" msgstr "" #: vobcopy.c:1827 #, c-format msgid "[Info] Single file size (of copied file %s ) %.0f\n" msgstr "" #: vobcopy.c:1828 #, c-format msgid "[Info] Cumulated size %.0f\n" msgstr "" #: vobcopy.c:1832 #, c-format msgid "[Info] Successfully copied file %s\n" msgstr "" #: vobcopy.c:1839 #, c-format msgid "[Info] # of separate files: %i\n" msgstr "" #: vobcopy.c:1849 #, c-format msgid "" "\n" "[Info] Copying finished! Let's see if the sizes match (roughly)\n" msgstr "" #: vobcopy.c:1850 #, c-format msgid "[Info] Combined size of title-vobs: %.0f (%.0f MB)\n" msgstr "" #: vobcopy.c:1851 #, c-format msgid "[Info] Copied size (size on disk): %.0f (%.0f MB)\n" msgstr "" #: vobcopy.c:1855 #, c-format msgid "[Error] Hmm, the sizes differ by more than %d\n" msgstr "" #: vobcopy.c:1856 #, c-format msgid "[Hint] Take a look with MPlayer if the output is ok\n" msgstr "" #: vobcopy.c:1860 #, c-format msgid "[Info] Everything seems to be fine, the sizes match pretty good ;-)\n" msgstr "" #: vobcopy.c:1861 #, c-format msgid "[Hint] Have a lot of fun!\n" msgstr "" #: vobcopy.c:1910 vobcopy.c:1954 #, c-format msgid "[Info] Used the linux statfs\n" msgstr "" #: vobcopy.c:1914 vobcopy.c:1958 #, c-format msgid "[Info] Used statvfs\n" msgstr "" #: vobcopy.c:1928 #, c-format msgid "[Info] In freespace_getter:for %s : %.0f free\n" msgstr "" #: vobcopy.c:1929 #, c-format msgid "[Info] In freespace_getter:bavail %ld * bsize %ld = above\n" msgstr "" #: vobcopy.c:1972 #, c-format msgid "[Info] In usedspace_getter:for %s : %.0f used\n" msgstr "" #: vobcopy.c:1973 #, c-format msgid "[Info] In usedspace_getter:part1 %ld, part2 %ld\n" msgstr "" #: vobcopy.c:2012 #, c-format msgid "" "\n" "[Info] Outputting to %s" msgstr "" #: vobcopy.c:2044 #, c-format msgid "[-l (large-file support for files > 2GB)] \n" msgstr "" #: vobcopy.c:2075 #, c-format msgid "[Error] Could not remove old filename: %s \n" msgstr "" #: vobcopy.c:2076 #, c-format msgid "[Hint] This: %s is a hardlink to %s. Dunno what to do... \n" msgstr "" #: vobcopy.c:2085 #, c-format msgid "[Error] File %s already exists! Gonna name the new one %s.dupe \n" msgstr "" #: vobcopy.c:2117 #, c-format msgid "[Error] The directory %s already exists!\n" msgstr "" #: vobcopy.c:2118 #, c-format msgid "[Hint] You can either [c]ontinue writing to it or you can [q]uit: " msgstr "" #: vobcopy.c:2136 #, c-format msgid "" "\n" "[Hint] please choose [c]ontinue or [q]uit the next time ;-)\n" msgstr "" #: vobcopy.c:2143 #, c-format msgid "" "[Error] Creating of directory %s\n" " failed! \n" msgstr "" #: vobcopy.c:2168 #, c-format msgid "" "\n" "[Info] Timer expired - shooting myself in the head.\n" msgstr "" #: vobcopy.c:2174 #, c-format msgid "" "\n" "[Info] Terminate signal received, exiting.\n" msgstr ""