par2cmdline-0.4/0000777000000000000000000000000010041760351007265 5par2cmdline-0.4/README0000644000000000000000000003023310041755255010071 par2cmdline is a PAR 2.0 compatible file verification and repair tool. See http://parchive.sourceforge.net for details of PAR 2.0 specification and discussion of all things PAR. WHAT EXACTLY IS PAR2CMDLINE? par2cmdline is a program for creating and using PAR2 files to detect damage in data files and repair them if necessary. It can be used with any kind of file. WHY IS PAR 2.0 better than PAR 1.0? * It is not necessary to split a single large file into many equally size small files (although you can still do so if you wish). * There is no loss of efficiency when operating on multiple files of different sizes. * It is possible to repair damaged files (using exactly the amount of recovery data that corresponds to the amount of damage), rather than requiring the complete reconstruction of the damaged file. * Recovery files may be of different sizes making it possible to obtain exactly the amount of recovery data required to carry out a repair. * Because damaged data files are still useable during the recovery process, less recovery data is required to achieve a successfull repair. It is not therefore necessary to create as much recovery data in the first place to achieve the same level of protection. * You can protect up to 32768 files rather than the 256 that PAR 1.0 is limited to. * Damaged or incomplete recovery files can also be used during the recovery process in the same way that damaged data files can. * You require less recovery data to provide the same level of protection from damage compared with PAR 1.0. DOES PAR 2.0 HAVE ANY DISSADVANTAGES? Yes, there is one dissadvantage: * All PAR 2.0 program will take somewhat longer to create recovery files than a PAR 1.0 program does. This dissadvantage is considerably mitigated by the fact that you don't need to create as much recovery data in the first place to provide the same level of protection against loss and damage. COMPILING PAR2CMDLINE You should have received par2cmdline in the form of source code which you can compile on your computer. You may optionally have received a pre-compiled version of the program for your operating system. If you have only downloaded a precompiled executable, then the source code should be available from the same location that you downloaded the executable from. If you have MS Visual Studio .NET, then just open the par2cmdline.sln file and compile. You should then copy par2cmdline.exe to an appropriate location that is on your path. To compile on Linux and other unix variants use the following commands: ./configure make make check make install See INSTALL for full details of how to use the "configure" script. USING PAR2CMDLINE The command line parameters for par2cmdline are as follow: par2 c(reate) [options] [files] par2 v(erify) [options] [files] par2 r(epair) [options] [files] Also: par2create [options] [files] par2verify [options] [files] par2repair [options] [files] Options: -b : Set the Block-Count -s : Set the Block-Size (Don't use both -b and -s) -r : Level of Redundancy (%) -c : Recovery block count (don't use both -r and -c) -f : First Recovery-Block-Number -u : Uniform recovery file sizes -l : Limit size of recovery files (Don't use both -u and -l) -n : Number of recovery files (Don't use both -n and -l) -m : Memory (in MB) to use -v [-v]: Be more verbose -q [-q]: Be more quiet (-qq gives silence) -- : Treat all remaining CommandLine as filenames If you wish to create par2 files for a single source file, you may leave out the name of the par2 file from the command line. par2cmdline will then assume that you wish to base the filenames for the par2 files on the name of the source file. You may also leave off the .par2 file extension when verifying and repairing. CREATING PAR2 FILES With PAR 2.0 you can create PAR2 recovery files for as few as 1 or as many as 32768 files. If you wanted to create PAR1 recovery files for a single file you are forced to split the file into muliple parts and RAR is frequently used for this purpose. You do NOT need to split files with PAR 2.0. To create PAR 2 recovery files for a single data file (e.g. one called test.mpg), you can use the following command: par2 create test.mpg If test.mpg is an 800 MB file, then this will create a total of 8 PAR2 files with the following filenames (taking roughly 6 minutes on a PC with a 1500MHz CPU): test.mpg.par2 - This is an index file for verification only test.mpg.vol00+01.par2 - Recovery file with 1 recovery block test.mpg.vol01+02.par2 - Recovery file with 2 recovery blocks test.mpg.vol03+04.par2 - Recovery file with 4 recovery blocks test.mpg.vol07+08.par2 - Recovery file with 8 recovery blocks test.mpg.vol15+16.par2 - Recovery file with 16 recovery blocks test.mpg.vol31+32.par2 - Recovery file with 32 recovery blocks test.mpg.vol63+37.par2 - Recovery file with 37 recovery blocks The test.mpg.par2 file is 39 KB in size and the other files vary in size from 443 KB to 15 MB. These par2 files will enable the recovery of up to 100 errors totalling 40 MB of lost or damaged data from the original test.mpg file when it and the par2 files are posted on UseNet. When posting on UseNet it is recommended that you use the "-s" option to set a blocksize that is equal to the Article size that you will use to post the data file. If you wanted to post the test.mpg file using an article size of 300 KB then the command you would type is: par2 create -s307200 test.mpg This will create 9 PAR2 files instead of 8, and they will be capable of correcting up to 134 errors totalling 40 MB. It will take roughly 8 minutes to create the recovery files this time. In both of these two examples, the total quantity of recovery data created was 40 MB (which is 5% of 800 MB). If you wish to create a greater or lesser quantity of recovery data, you can use the "-r" option. To create 10% recovery data instead of the default of 5% and also to use a block size of 300 KB, you would use the following command: par2 create -s307200 -r10 test.mpg This would also create 9 PAR2 files, but they would be able to correct up to 269 errors totalling 80 MB. Since twice as much recovery data is created, it will take about 16 minutes to do so with a 1500MHz CPU. The "-u" and "-n" options can be used to control exactly how many recovery files are created and how the recovery blocks are distributed amoungst them. They do not affect the total quantity of recovery data created. The "-f" option is used when you create additional recovery data. e.g. If you have already created 10% and want another 5% then you migh use the following command: par2 create -s307200 -r5 -f300 test.mpg This specifies the same block size (which is a requirement for additional recovery files), 5% recovery data, and a first block number of 300. The "-m" option controls how much memory par2cmdline uses. It defaults to 16 MB unless you override it. CREATING PAR2 FILES FOR MULTIPLE DATA FILES When creating PAR2 recovery files form multiple data files, you must specify the base filename to use for the par2 files and the names of all of the data files. If test.mpg had been split into multiple RAR files, then you could use: par2 create test.mpg.rar.par2 test.mpg.part*.rar The files filename "test.mpg.rar.par2" says what you want the par2 files to be called and "test.mpg.part*.rar" should select all of the RAR files. VERIFYING AND REPAIRING When using par2 recovery files to verify or repair the data files from which they were created, you only need to specify the filename of one of the par2 files to par2cmdline. e.g.: par2 verify test.mpg.par2 This tells par2cmdline to use the information in test.mpg.par2 to verify the data files. par2cmdline will automatically search for the other par2 files that were created and use the information they contain to determine the filenames of the original data files and then to verify them. If all of the data files are ok, then par2cmdline will report that repair will not be required. If any of the data files are missing or damaged, par2cmdline will report the details of what it has found. If the recovery files contain enough recovery blocks to repair the damage, you will be told that repair is possible. Otherwise you will be told exactly how many recovery blocks will be required in order to repair. To carry out a repair use the following command: par2 repair test.mpg.par2 This tells par2cmdline to verify and if possible repair any damaged or missing files. If a repair is carried out, then each file which is repaired will be re-verified to confirm that the repair was successful. MISSNAMED AND INCOMPLETE DATA FILES If any of the recovery files or data files have the wrong filename, then par2cmdline will not automatically find and scan them. To have par2cmdline scan such files, you must include them on the command line when attempting to verify or repair. e.g.: par2 r test.mpg.par2 other.mpg This tells par2cmdline to scan the file called other.mpg to see if it contains any data belonging to the original data files. If one of the extra files specified in this way is an exact match for a data file, then the repair process will rename the file so that it has the correct filename. Because par2cmdline is designed to be able to find good data within a damaged file, it can do the same with incomplete files downloaded from UseNet. If some of the articles for a file are missing, you should still download the file and save it to disk for par2cmdline to scan. If you do this then you may find that you can carry out a repair in a situation where you would not otherwise have sufficient recovery data. You can have par2cmdline scan all files that are in the current directory using a command such as: par2 r test.mpg.par2 * WHAT TO DO WHEN YOU ARE TOLD YOU NEED MORE RECOVERY BLOCKS If par2cmdline determines that any of the data files are damaged or missing and finds that there is insufficient recovery data to effect a repair, you will be told that you need a certain number of recovery blocks. You can obtain these by downloading additional recovery files. In order to make things easy, par2 files have filenames that tell you exactly how many recovery blocks each one contains. Assuming that the following command was used to create recovery data: par2 c -b1000 -r5 test.mpg Then the recovery files that are created would be called: test.mpg.par2 test.mpg.vol00+01.par2 test.mpg.vol01+02.par2 test.mpg.vol03+04.par2 test.mpg.vol07+08.par2 test.mpg.vol15+16.par2 test.mpg.vol31+19.par2 The first file in this list does not contain any recovery data, it only contains information sufficient to verify the data files. Each of the other files contains a different number of recovery blocks. The number after the '+' sign is the number of recovery blocks and the number preceding the '+' sign is the block number of the first recovery block in that file. If par2cmdline told you that you needed 10 recovery blocks, then you would need "test.mpg.vol01+02.par2" and "test.mpg.vol07+08.par". You might of course choose to fetch "test.mpg.vol15+16.par2" instead (in which case you would have an extra 6 recovery blocks which would not be used for the repair). NOTES This version of par2cmdline does not support recording path information for files. Whilst you can create recovery files for files from multiple locations, it will expect all files to be in the current directory when verifying and repairing. This limitation will be corrected in an update. REED SOLOMON CODING PAR2 uses Reed Solomon Coding to perform its calculations. For details of this coding technique try the following link: ``A Tutorial on Reed-Solomon Coding for Fault-Tolerance in RAID-like Systems'' par2cmdline-0.4/configure.ac0000755000000000000000000000357210036543377011514 dnl This file is part of par2cmdline (a PAR 2.0 compatible file verification and dnl repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. dnl dnl Copyright (c) 2003 Peter Brian Clements dnl dnl par2cmdline is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl par2cmdline is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.58a) AC_INIT([par2cmdline], [0.4], [peterbclements@users.sourceforge.net]) AC_CONFIG_SRCDIR([par2cmdline.cpp]) AC_CANONICAL_HOST AM_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE dnl Checks for programs. AC_PROG_CXX AC_PROG_INSTALL dnl Checks for libraries. dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDBOOL AC_HEADER_STDC AC_CHECK_HEADERS([stdio.h] [endian.h]) AC_CHECK_HEADERS([getopt.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_C_BIGENDIAN AC_C_CONST AC_C_INLINE AC_SYS_LARGEFILE AC_FUNC_FSEEKO dnl Checks for library functions. AC_FUNC_MEMCMP AC_CHECK_FUNCS([stricmp] [strcasecmp]) AC_CHECK_FUNCS([strchr] [memcpy]) AC_CHECK_FUNCS([getopt] [getopt_long]) AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT par2cmdline-0.4/aclocal.m40000644000000000000000000010433110036543525011051 # generated automatically by aclocal 1.8.3 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # -*- Autoconf -*- # Copyright (C) 2002, 2003 Free Software Foundation, Inc. # Generated from amversion.in; do not edit by hand. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.8.3])]) # AM_AUX_DIR_EXPAND # Copyright (C) 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 6 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]) fi])]) # serial 7 -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 7 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 11 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright (C) 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # -*- Autoconf -*- # Copyright (C) 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # Copyright (C) 2003, 2004 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # Keeping the `.' argument allows $(mkdir_p) to be used without # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more # expensive solution, as it forces Make to start a sub-shell.) mkdir_p='mkdir -p -- .' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # AM_PROG_INSTALL_STRIP # Copyright (C) 2001, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) par2cmdline-0.4/Makefile.am0000755000000000000000000000474110036543210011243 ## This file is part of par2cmdline (a PAR 2.0 compatible file verification and ## repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. ## ## Copyright (c) 2003 Peter Brian Clements ## ## par2cmdline 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. ## ## par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA bin_PROGRAMS = par2 par2_SOURCES = par2cmdline.cpp par2cmdline.h \ commandline.cpp commandline.h \ crc.cpp crc.h \ creatorpacket.cpp creatorpacket.h \ criticalpacket.cpp criticalpacket.h \ datablock.cpp datablock.h \ descriptionpacket.cpp descriptionpacket.h \ diskfile.cpp diskfile.h \ filechecksummer.cpp filechecksummer.h \ galois.cpp galois.h \ letype.h \ mainpacket.cpp mainpacket.h \ md5.cpp md5.h \ par1fileformat.cpp par1fileformat.h \ par1repairer.cpp par1repairer.h \ par1repairersourcefile.cpp par1repairersourcefile.h \ par2creator.cpp par2creator.h \ par2creatorsourcefile.cpp par2creatorsourcefile.h \ par2fileformat.cpp par2fileformat.h \ par2repairer.cpp par2repairer.h \ par2repairersourcefile.cpp par2repairersourcefile.h \ recoverypacket.cpp recoverypacket.h \ reedsolomon.cpp reedsolomon.h \ verificationhashtable.cpp verificationhashtable.h \ verificationpacket.cpp verificationpacket.h LDADD = -lstdc++ AM_CXXFLAGS = -Wall EXTRA_DIST = PORTING ROADMAP par2cmdline.sln par2cmdline.vcproj \ testdata.tar.gz pretest test1 test2 test3 test4 test5 test6 \ posttest TESTS = pretest test1 test2 test3 test4 test5 test6 posttest install-exec-hook : ln -f $(DESTDIR)$(bindir)/par2$(EXEEXT) $(DESTDIR)$(bindir)/par2create$(EXEEXT) ln -f $(DESTDIR)$(bindir)/par2$(EXEEXT) $(DESTDIR)$(bindir)/par2verify$(EXEEXT) ln -f $(DESTDIR)$(bindir)/par2$(EXEEXT) $(DESTDIR)$(bindir)/par2repair$(EXEEXT) uninstall-hook : rm -f $(DESTDIR)$(bindir)/par2create$(EXEEXT) rm -f $(DESTDIR)$(bindir)/par2verify$(EXEEXT) rm -f $(DESTDIR)$(bindir)/par2repair$(EXEEXT) par2cmdline-0.4/Makefile.in0000644000000000000000000006133510036543542011263 # Makefile.in generated by automake 1.8.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ SOURCES = $(par2_SOURCES) srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_triplet = @host@ bin_PROGRAMS = par2$(EXEEXT) DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/stamp-h.in $(top_srcdir)/configure AUTHORS COPYING \ ChangeLog INSTALL NEWS config.guess config.sub depcomp \ install-sh missing mkinstalldirs subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = stamp-h am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) am_par2_OBJECTS = par2cmdline.$(OBJEXT) commandline.$(OBJEXT) \ crc.$(OBJEXT) creatorpacket.$(OBJEXT) criticalpacket.$(OBJEXT) \ datablock.$(OBJEXT) descriptionpacket.$(OBJEXT) \ diskfile.$(OBJEXT) filechecksummer.$(OBJEXT) galois.$(OBJEXT) \ mainpacket.$(OBJEXT) md5.$(OBJEXT) par1fileformat.$(OBJEXT) \ par1repairer.$(OBJEXT) par1repairersourcefile.$(OBJEXT) \ par2creator.$(OBJEXT) par2creatorsourcefile.$(OBJEXT) \ par2fileformat.$(OBJEXT) par2repairer.$(OBJEXT) \ par2repairersourcefile.$(OBJEXT) recoverypacket.$(OBJEXT) \ reedsolomon.$(OBJEXT) verificationhashtable.$(OBJEXT) \ verificationpacket.$(OBJEXT) par2_OBJECTS = $(am_par2_OBJECTS) par2_LDADD = $(LDADD) par2_DEPENDENCIES = DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/commandline.Po ./$(DEPDIR)/crc.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/creatorpacket.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/criticalpacket.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/datablock.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/descriptionpacket.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/diskfile.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/filechecksummer.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/galois.Po ./$(DEPDIR)/mainpacket.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/md5.Po ./$(DEPDIR)/par1fileformat.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par1repairer.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par1repairersourcefile.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par2cmdline.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par2creator.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par2creatorsourcefile.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par2fileformat.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par2repairer.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/par2repairersourcefile.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/recoverypacket.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/reedsolomon.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/verificationhashtable.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/verificationpacket.Po CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(par2_SOURCES) DIST_SOURCES = $(par2_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ par2_SOURCES = par2cmdline.cpp par2cmdline.h \ commandline.cpp commandline.h \ crc.cpp crc.h \ creatorpacket.cpp creatorpacket.h \ criticalpacket.cpp criticalpacket.h \ datablock.cpp datablock.h \ descriptionpacket.cpp descriptionpacket.h \ diskfile.cpp diskfile.h \ filechecksummer.cpp filechecksummer.h \ galois.cpp galois.h \ letype.h \ mainpacket.cpp mainpacket.h \ md5.cpp md5.h \ par1fileformat.cpp par1fileformat.h \ par1repairer.cpp par1repairer.h \ par1repairersourcefile.cpp par1repairersourcefile.h \ par2creator.cpp par2creator.h \ par2creatorsourcefile.cpp par2creatorsourcefile.h \ par2fileformat.cpp par2fileformat.h \ par2repairer.cpp par2repairer.h \ par2repairersourcefile.cpp par2repairersourcefile.h \ recoverypacket.cpp recoverypacket.h \ reedsolomon.cpp reedsolomon.h \ verificationhashtable.cpp verificationhashtable.h \ verificationpacket.cpp verificationpacket.h LDADD = -lstdc++ AM_CXXFLAGS = -Wall EXTRA_DIST = PORTING ROADMAP par2cmdline.sln par2cmdline.vcproj \ testdata.tar.gz pretest test1 test2 test3 test4 test5 test6 \ posttest TESTS = pretest test1 test2 test3 test4 test5 test6 posttest all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ cd $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 stamp-h: $(top_builddir)/config.status $(srcdir)/stamp-h.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) par2$(EXEEXT): $(par2_OBJECTS) $(par2_DEPENDENCIES) @rm -f par2$(EXEEXT) $(CXXLINK) $(par2_LDFLAGS) $(par2_OBJECTS) $(par2_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commandline.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/creatorpacket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/criticalpacket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/datablock.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/descriptionpacket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filechecksummer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/galois.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mainpacket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par1fileformat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par1repairer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par1repairersourcefile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par2cmdline.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par2creator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par2creatorsourcefile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par2fileformat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par2repairer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/par2repairersourcefile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recoverypacket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reedsolomon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verificationhashtable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verificationpacket.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list='$(TESTS)'; \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ ;; \ *) \ echo "PASS: $$tst"; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *" $$tst "*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ *) \ failed=`expr $$failed + 1`; \ echo "FAIL: $$tst"; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ echo "SKIP: $$tst"; \ fi; \ done; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="All $$all tests passed"; \ else \ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all tests failed"; \ else \ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ skipped="($$skip tests were not run)"; \ test `echo "$$skipped" | wc -c` -gt `echo "$$banner" | wc -c` && \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -gt `echo "$$banner" | wc -c` && \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ test -n "$$skipped" && echo "$$skipped"; \ test -n "$$report" && echo "$$report"; \ echo "$$dashes"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkdir_p) $(distdir)/. @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) config.h installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-binPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-info-am @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ clean clean-binPROGRAMS clean-generic ctags dist dist-all \ dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip distcheck \ distclean distclean-compile distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-info-am install-exec-hook : ln -f $(DESTDIR)$(bindir)/par2$(EXEEXT) $(DESTDIR)$(bindir)/par2create$(EXEEXT) ln -f $(DESTDIR)$(bindir)/par2$(EXEEXT) $(DESTDIR)$(bindir)/par2verify$(EXEEXT) ln -f $(DESTDIR)$(bindir)/par2$(EXEEXT) $(DESTDIR)$(bindir)/par2repair$(EXEEXT) uninstall-hook : rm -f $(DESTDIR)$(bindir)/par2create$(EXEEXT) rm -f $(DESTDIR)$(bindir)/par2verify$(EXEEXT) rm -f $(DESTDIR)$(bindir)/par2repair$(EXEEXT) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: par2cmdline-0.4/config.h.in0000644000000000000000000000664510036543647011252 /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ #undef HAVE_FSEEKO /* Define to 1 if you have the `getopt' function. */ #undef HAVE_GETOPT /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `stricmp' function. */ #undef HAVE_STRICMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ #undef _LARGEFILE_SOURCE /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `unsigned' if does not define. */ #undef size_t par2cmdline-0.4/stamp-h.in0000755000000000000000000000000007664453174011116 par2cmdline-0.4/configure0000755000000000000000000067561710036543546011147 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for par2cmdline 0.4. # # Report bugs to . # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='par2cmdline' PACKAGE_TARNAME='par2cmdline' PACKAGE_VERSION='0.4' PACKAGE_STRING='par2cmdline 0.4' PACKAGE_BUGREPORT='peterbclements@users.sourceforge.net' ac_unique_file="par2cmdline.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures par2cmdline 0.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of par2cmdline 0.4:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --disable-largefile omit support for large files Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF par2cmdline configure 0.4 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by par2cmdline $as_me 0.4, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 echo "$as_me: error: cannot run $ac_config_sub" >&2;} { (exit 1); exit 1; }; } echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6 if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_build_alias=$build_alias test -z "$ac_cv_build_alias" && ac_cv_build_alias=`$ac_config_guess` test -z "$ac_cv_build_alias" && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6 build=$ac_cv_build build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6 if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_host_alias=$host_alias test -z "$ac_cv_host_alias" && ac_cv_host_alias=$ac_cv_build_alias ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6 host=$ac_cv_host host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ac_config_headers="$ac_config_headers config.h" am__api_version="1.8" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 test "$program_prefix" != NONE && program_transform_name="s,^,$program_prefix,;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$,$program_suffix,;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # Keeping the `.' argument allows $(mkdir_p) to be used without # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more # expensive solution, as it forces Make to start a sub-shell.) mkdir_p='mkdir -p -- .' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='par2cmdline' VERSION='0.4' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_opendir=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_opendir" = no; then for ac_lib in dir; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6 if test "$ac_cv_search_opendir" != no; then test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" fi else echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_opendir=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_opendir" = no; then for ac_lib in x; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6 if test "$ac_cv_search_opendir" != no; then test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6 if test "${ac_cv_header_stdbool_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifndef bool # error bool is not defined #endif #ifndef false # error false is not defined #endif #if false # error false is not 0 #endif #ifndef true # error true is not defined #endif #if true != 1 # error true is not 1 #endif #ifndef __bool_true_false_are_defined # error __bool_true_false_are_defined is not defined #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) -0.5 == true ? 1 : -1]; bool e = &s; char f[(_Bool) -0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; int main () { return !a + !b + !c + !d + !e + !f + !g + !h + !i; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdbool_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdbool_h=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6 echo "$as_me:$LINENO: checking for _Bool" >&5 echo $ECHO_N "checking for _Bool... $ECHO_C" >&6 if test "${ac_cv_type__Bool+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((_Bool *) 0) return 0; if (sizeof (_Bool)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type__Bool=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type__Bool=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 echo "${ECHO_T}$ac_cv_type__Bool" >&6 if test $ac_cv_type__Bool = yes; then cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STDBOOL_H 1 _ACEOF fi echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi for ac_header in stdio.h endian.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------------------- ## ## Report this to peterbclements@users.sourceforge.net ## ## --------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in getopt.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------------------- ## ## Report this to peterbclements@users.sourceforge.net ## ## --------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned _ACEOF fi echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long l; char c[sizeof (long)]; } u; u.l = 1; exit (u.c[sizeof (long) - 1] == 1); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6 case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6 if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_inline=$ac_kw; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done fi echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6 case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac # Check whether --enable-largefile or --disable-largefile was given. if test "${enable_largefile+set}" = set; then enableval="$enable_largefile" fi; if test "$enable_largefile" != no; then echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6 if test "${ac_cv_sys_largefile_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext CC="$CC -n32" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sys_largefile_CC=' -n32'; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6 if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6 if test "${ac_cv_sys_file_offset_bits+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do ac_cv_sys_file_offset_bits=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sys_file_offset_bits=64; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext break done fi echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6 if test "$ac_cv_sys_file_offset_bits" != no; then cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF fi rm -f conftest* echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6 if test "${ac_cv_sys_large_files+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do ac_cv_sys_large_files=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sys_large_files=1; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext break done fi echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 echo "${ECHO_T}$ac_cv_sys_large_files" >&6 if test "$ac_cv_sys_large_files" != no; then cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF fi rm -f conftest* fi echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5 echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6 if test "${ac_cv_sys_largefile_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do ac_cv_sys_largefile_source=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { return !fseeko; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include int main () { return !fseeko; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sys_largefile_source=1; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext break done fi echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5 echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6 if test "$ac_cv_sys_largefile_source" != no; then cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF fi rm -f conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. echo "$as_me:$LINENO: checking for fseeko" >&5 echo $ECHO_N "checking for fseeko... $ECHO_C" >&6 if test "${ac_cv_func_fseeko+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { return fseeko && fseeko (stdin, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_fseeko=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_fseeko=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_fseeko" >&5 echo "${ECHO_T}$ac_cv_func_fseeko" >&6 if test $ac_cv_func_fseeko = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_FSEEKO 1 _ACEOF fi echo "$as_me:$LINENO: checking for working memcmp" >&5 echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6 if test "${ac_cv_func_memcmp_working+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_memcmp_working=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Some versions of memcmp are not 8-bit clean. */ char c0 = 0x40, c1 = 0x80, c2 = 0x81; if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) exit (1); /* The Next x86 OpenStep bug shows up only when comparing 16 bytes or more and with at least one buffer not starting on a 4-byte boundary. William Lewis provided this test program. */ { char foo[21]; char bar[21]; int i; for (i = 0; i < 4; i++) { char *a = foo + i; char *b = bar + i; strcpy (a, "--------01111111"); strcpy (b, "--------10000000"); if (memcmp (a, b, 16) >= 0) exit (1); } exit (0); } ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_memcmp_working=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_memcmp_working=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6 test $ac_cv_func_memcmp_working = no && case $LIBOBJS in "memcmp.$ac_objext" | \ *" memcmp.$ac_objext" | \ "memcmp.$ac_objext "* | \ *" memcmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;; esac for ac_func in stricmp strcasecmp do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strchr memcpy do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getopt getopt_long do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_config_files="$ac_config_files stamp-h" ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by par2cmdline $as_me 0.4, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ par2cmdline config.status 0.4 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "stamp-h" ) CONFIG_FILES="$CONFIG_FILES stamp-h" ;; "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t s,@build_vendor@,$build_vendor,;t t s,@build_os@,$build_os,;t t s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@CYGPATH_W@,$CYGPATH_W,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@mkdir_p@,$mkdir_p,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CXXDEPMODE@,$CXXDEPMODE,;t t s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi # Run the commands associated with the file. case $ac_file in stamp-h ) echo timestamp > stamp-h ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } # Do quote $f, to prevent DOS paths from being IFS'd. echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # And first: Protect against being on the right side of a sed subst in # config.status. Protect against being in an unquoted here document # in config.status. rm -f conftest.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi # Compute $ac_file's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $ac_file | $ac_file:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X$ac_file : 'X\(//\)[^/]' \| \ X$ac_file : 'X\(//\)$' \| \ X$ac_file : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X$ac_file | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'`/stamp-h$_am_stamp_count done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi par2cmdline-0.4/AUTHORS0000644000000000000000000000007507664453133010271 Peter Brian Clements par2cmdline-0.4/COPYING0000644000000000000000000004311010036536617010245 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year 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. par2cmdline-0.4/ChangeLog0000755000000000000000000002163010041760340010756 22 April 2004 Peter B Clements * README: Updated to include new commandline options. * par2cmdline.vcproj: Update VS .NET project file with new version number. * Released: Version 0.4. 15 April 2004 Peter B Clements * par2cmdline.sln, par2cmdline.vcproj: Updated. * commandline.cpp, commandline.h, par1repairer.cpp, par1repairer.h, par2cmdline.cpp, par2cmdline.h, par2creator.cpp, par2creator.h, par2creatorsourcefile.cpp, par2creatorsourcefile.h, par2repairer.cpp, par2repairer.h, reedsolomon.h, par2cmdline.h: Handle -v and -q options from the command line to change the amount of messages displayed. 14 April 2004 Peter B Clements * commandline.h, commandline.cpp: Add -c option to allow the number of recovery blocks to be directly specified rather than indirectly via the -r option. Add -l option to allow the recovery file size to be limited so that the largest will have just enough recovery data to reconstruct the larget source file. * par2creator.h, par2creator.cpp: Use the recovery block count specified via the command line instead of the redundancy % if given. Allocate the sizes of recovery files so the are limited if requested. 12 April 2004 Peter B Clements * config.h.in, configure, configure.ac: Detect what defines are required to enable 64 bit file system support and whether or not fseeko() is available. * diskfile.cpp: Use fseeko and 64 bit file operations if they are available. * par2cmdline.h: Change order of include files. * par2repairer.cpp: When verifying files with long filenames, display a shorter version of the filename. * datablock.h: Change DataBlock::GetDiskFile so that in returns a non const DiskFile. * par2repairer.cpp, par2creator.cpp: Only keep source files open when they are actually needed. This should allow par2 creation and repair to work with large file sets on OS's with a limit on the number of files that can be open simultaneously. * Makefile.in, aclocal.m4, config.guess, config.sub, configure, depcomp, install-sh, missing, mkinstalldirs: Updated Automake to version 1.8.3 and Autoconf to version 2.59. * configure.ac, config.h.in, configure: Check for getopt() and getopt_long(). 19 August 2003 Peter B Clements * Updated par2creator.cpp: When creating par2 files the wrong number of bytes would be reported as written to disk. 13 August 2003 Peter B Clements * Updated par2cmdline.h: Recorrected spelling of STDC_HEADERS! * Updated par1repairersourcefile.cpp, par2repairersourcefile.cpp: Don't treat ':' as a path separator on non Windows platforms. 2 August 2003 Peter B Clements * Updated par1fileformat.h, par2fileformat.h: Use memcmp when comparing MAGIC strings and PACKETTYPE strings. * Updated par2repairer.cpp: When a good packet is found after bad data, use memcpy to copy the packet header. Don't attempt to get the block count directly from the verification packet (which might be missing). * Updated par2repairersourcefile.cpp: Add function to set the block count when the verification packet is missing. 1 August 2003 Peter B Clements * Updated par2cmdline.h: Included . 31 July 2003 Peter B Clements * Updated reedsolomon.h: Added debugging code. 29 July 2003 Peter B Clements * Updated galois.h: Use typename when refering to a typedef in another class. * Updated par1repairer.cpp: Cast size of fileentry in memcpy. * Updated par2repairersourcefile.h: Add function to set the block count for a file when the verification packet is missing. 25 July 2003 Peter B Clements * Updated par2cmdline.h: Correct spelling of STDC_HEADERS. 16 July 2003 Peter B Clements * Release: Version 0.3. 15 July 2003 Peter B Clements * Added config.guess, config.sub: Autoconf files. * Updated configure, Makefile.in: Updated by Autoconf. * Updated configure.ac: Changed par2cmdline version number. Added call to AC_CANONICAL_HOST. * Updated par2cmdline.vcproj: Updated version number. 3 July 2003 Peter B Clements * Updated aclocal.m4, depcomp, INSTALL, install-sh, mkinstalldirs: Upgrade Autoconf to version 1.75 from 1.6.3. * Updated Makefile.am: Changed CXXFLAGS to AM_CXXFLAGS. 24 June 2003 Peter B Clements * Updated commandline.cpp, commandline.h: Added "redundancyseet" member to record whether or not the value of "redundancy" has been specified so that 0% reduncancy is permissible. * Updated par2creator.cpp: Detect situation where no recovery blocks are being created and skip related code sections. 14 June 2003 Peter B Clements * Updated galois.h: Corrected bug in the initialisation of log[0] in GaloisTable. 11 June 2003 Peter B Clements * Updated par1repair.cpp, par1repairer.h: Detect buggy version of smartpar which creates PAR1 files with invalid 16k hash values, Change alignement of temporary buffer used for PAR1FILEENTRYs to 8 bytes. 7 June 2003 Peter B Clements * Update par2cmdline.h: Added header include. 3 June 2003 Peter B Clements * Updated verificationhashtable.h: Fixed bug where blocks of data that have the same crc and hash would not be correctly recognised. 26 May 2003 Peter B Clements * Release: Version 0.2. * Added config.h.in, configure, configure.ac, depcomp, missing, mkinstalldirs, stamp-h.in: Autoconf configuration files. * Added NEWS * Added par1fileformat.h, par1fileformat.cpp: Specifies the layout of PAR 1.0 files. * Added par1repairer.h, par1repairer.cpp: Encapsulates the details of repairing using PAR 1.0 files. * Added par1repairersourcefile.h, par1repairersourcefile.cpp: Stores details of a source file. * Added test1, test2, test3, test4, test5, test6, testdata.tar.gz: Test files for "make check". * Changed commandline.cpp, commandline.h: Add "version" member and set it according to whether the recovery file is a .PAR file or a .PAR2 file. Rename "par2filename" member to "parfilename". * Changed creatorpacket.cpp: Made "string creator" a local variable in CreatorPacket::Create instead of a global. Commented out code that does nothing. * Changed criticalpacket.h: Corrected bug in CriticalPacketEntry::operator= which failed to return *this. * Changed descriptionpacket.cpp: Commented out code which does nothing. * Changed diskfile.cpp: Updated wildcard matching code to permit multiple "?" in wildcard. Adjusted the list of characters that are accepted in filenames to include all with bit 7 set and also spaces. Removed restrictions on many other permitted characters. * Changed diskfile.h: Removed cygwin and linux ifdefs which are now handled by autoconf. * Changed galois.cpp: Move the constructors for GaloisTable and GaloisLongMultiplyTable to galois.h. * Changed galois.h: Changed GaloisTable, Galois, and GaloisLongMultipleTable into templates. Corrected bug in Galois::pow and Galois::operator^ which incorrectly returned 0 for x^0 when it should always return 1. Added Galois8 and Galois16 typedefs for PAR1 and PAR2. * Changed letype.h: Added leu16 type for use in PAR1 processing. * Changed mainpacket.cpp: Commented out code which does nothing. * Changed md5.cpp: Adjusted ROL macro to include masking to correct for bug on Alpha CPUs. Added operator<<() and print() to MD5Hash. * Changed md5.h: Added copy and assignment operators for MD5Hash. * Changed par2cmdline.cpp: Made "string version" a local variable instead of global. Use Par1Repairer or Par2Repaire as appropriate when verifying or repairing PAR1 and PAR2 files. * Changed par2cmdline.h: Adjusted to conditionally include headers and to define various types based on the autoconf configuration. * Changed par2cmdline.sln, par2cmdline.vcproj: Updated. * Changed par2creator.cpp: Called Commandline::GetParFilename instead of CommandLine::GetPar2Filename. * Changed par2creator.h: Redifine rs as ReedSolomon. * Changed par2creatorsourcefile.cpp: Comment out code which does nothing. Added typecasts between 32bit and 64bit values. * Changed par2fileformat.cpp: Adjusted initialisation code. * Changed par2fileformat.h: Use packed attribute for gnu compilers. * Changed par2repairer.cpp: Get filename using CommandLine::GetParFilename. * Changed par2repairer.h: Redefine rs as ReedSolomon. * Changed par2repairersourcefile: Add typecast from 32bit to 64bit. * Changed README: Update details of how to compile the source code using the configure script. * Changed recoverypacket.cpp: Commented out code which does nothing. * Changed ReedSolomon.cpp: Move ReedSolomon constructor to ReedSolomon.h. Created template specialisations for Galois8 and Galois16 for SetInput, SetOutput, and Process. * Changed ReedSolomon.h: Converted ReedSolomon to a template. * Changed verificationhashtable.cpp: Removed unused code. * Changed verificationpacket.cpp: Commented out code that does nothing. 7 May 2003 Peter B Clements * Version 0.1: Initial release. par2cmdline-0.4/INSTALL0000644000000000000000000002203010036536617010241 Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. par2cmdline-0.4/NEWS0000755000000000000000000000000007664453160007707 par2cmdline-0.4/config.guess0000755000000000000000000012502010036536620011525 #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2004-03-03' # This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amd64:OpenBSD:*:*) echo x86_64-unknown-openbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; cats:OpenBSD:*:*) echo arm-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pegasos:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit 0 ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit 0 ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha*:OpenVMS:*:*) echo alpha-hp-vms exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; *:OS400:*:*) echo powerpc-ibm-os400 exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit 0 ;; DRS?6000:UNIX_SV:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && exit 0 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then # avoid double evaluation of $set_cc_for_build test -n "$CC_FOR_BUILD" || eval $set_cc_for_build if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) # Determine whether the default compiler uses glibc. eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #if __GLIBC__ >= 2 LIBC=gnu #else LIBC= #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` # GNU/KFreeBSD systems have a "k" prefix to indicate we are using # FreeBSD's kernel, but not the complete OS. case ${LIBC} in gnu) kernel_only='k' ;; esac echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit 0 ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit 0 ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) case `uname -p` in *86) UNAME_PROCESSOR=i686 ;; powerpc) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit 0 ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: par2cmdline-0.4/config.sub0000755000000000000000000007460410036536620011203 #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2004-02-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m68000 | m68k | m88k | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | msp430-* \ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nv1) basic_machine=nv1-cray os=-unicosmp ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: par2cmdline-0.4/depcomp0000755000000000000000000003477110036536621010577 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2003-11-08.23 # Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit 0 ;; -v | --v*) echo "depcomp $scriptversion" exit 0 ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: par2cmdline-0.4/install-sh0000755000000000000000000002177010036536620011220 #!/bin/sh # install - install a program, script, or datafile scriptversion=2004-02-15.20 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename= transform_arg= instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= usage="Usage: $0 [OPTION]... SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 -d DIRECTORIES... In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. In the second, create the directory path DIR. Options: -b=TRANSFORMBASENAME -c copy source (using $cpprog) instead of moving (using $mvprog). -d create directories instead of installing files. -g GROUP $chgrp installed files to GROUP. -m MODE $chmod installed files to MODE. -o USER $chown installed files to USER. -s strip installed files (using $stripprog). -t=TRANSFORM --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) # When -d is used, all remaining arguments are directories to create. test -n "$dir_arg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then instcmd=: chmodcmd= else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" || lasterr=$? # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; } fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $instcmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else # If we're going to rename the final executable, determine the name now. if test -z "$transformarg"; then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename \ | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename. test -z "$dstfile" && dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now remove or move aside any old file at destination location. We # try this two ways since rm can't unlink itself on some systems and # the destination file might be busy for other reasons. In this case, # the final cleanup might fail but the new file should still install # successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi || { (exit 1); exit; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: par2cmdline-0.4/missing0000755000000000000000000002466610036536620010622 #! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2003-09-02.23 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: par2cmdline-0.4/mkinstalldirs0000755000000000000000000000653510036536620012024 #! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2004-02-15.20 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit 0 ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: par2cmdline-0.4/par2cmdline.cpp0000644000000000000000000000752210037473303012116 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif void banner(void) { string version = PACKAGE " version " VERSION; cout << version << ", Copyright (C) 2003 Peter Brian Clements." << endl << endl << "par2cmdline comes with ABSOLUTELY NO WARRANTY." << endl << endl << "This is free software, and you are welcome to redistribute it and/or modify" << endl << "it under the terms of the GNU General Public License as published by the" << endl << "Free Software Foundation; either version 2 of the License, or (at your" << endl << "option) any later version. See COPYING for details." << endl << endl; } int main(int argc, char *argv[]) { #ifdef _MSC_VER // Memory leak checking _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_ALLOC_MEM_DF | /*_CRTDBG_CHECK_CRT_DF | */_CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif // Parse the command line CommandLine *commandline = new CommandLine; Result result = eInvalidCommandLineArguments; if (!commandline->Parse(argc, argv)) { banner(); CommandLine::usage(); } else { if (commandline->GetNoiseLevel() > CommandLine::nlSilent) banner(); // Which operation was selected switch (commandline->GetOperation()) { case CommandLine::opCreate: { // Create recovery data Par2Creator *creator = new Par2Creator; result = creator->Process(*commandline); delete creator; } break; case CommandLine::opVerify: { // Verify damaged files switch (commandline->GetVersion()) { case CommandLine::verPar1: { Par1Repairer *repairer = new Par1Repairer; result = repairer->Process(*commandline, false); delete repairer; } break; case CommandLine::verPar2: { Par2Repairer *repairer = new Par2Repairer; result = repairer->Process(*commandline, false); delete repairer; } break; case CommandLine::opNone: break; } } break; case CommandLine::opRepair: { // Repair damaged files switch (commandline->GetVersion()) { case CommandLine::verPar1: { Par1Repairer *repairer = new Par1Repairer; result = repairer->Process(*commandline, true); delete repairer; } break; case CommandLine::verPar2: { Par2Repairer *repairer = new Par2Repairer; result = repairer->Process(*commandline, true); delete repairer; } break; case CommandLine::opNone: break; } } break; case CommandLine::opNone: break; } } delete commandline; return result; } par2cmdline-0.4/par2cmdline.h0000644000000000000000000001516410037507132011562 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PARCMDLINE_H__ #define __PARCMDLINE_H__ #ifdef WIN32 // Windows includes #define WIN32_LEAN_AND_MEAN #include // System includes #include #include #include #include #include #include #include #include #include #define snprintf _snprintf #define stat _stat #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 #define __PDP_ENDIAN 3412 #define __BYTE_ORDER __LITTLE_ENDIAN typedef unsigned char u8; typedef unsigned short u16; typedef unsigned long u32; typedef unsigned __int64 u64; #ifndef _SIZE_T_DEFINED # ifdef _WIN64 typedef unsigned __int64 size_t; # else typedef unsigned int size_t; # endif # define _SIZE_T_DEFINED #endif #else // WIN32 #ifdef HAVE_CONFIG_H #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STDIO_H # include #endif #if HAVE_DIRENT_H # include # define NAMELEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMELEN(dirent) (dirent)->d_namelen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif #if STDC_HEADERS # include #else # if !HAVE_STRCHR # define strchr index # define strrchr rindex # endif char *strchr(), *strrchr(); # if !HAVE_MEMCPY # define memcpy(d, s, n) bcopy((s), (d), (n)) # define memove(d, s, n) bcopy((s), (d), (n)) # endif #endif #if HAVE_MEMORY_H # include #endif #if !HAVE_STRICMP # if HAVE_STRCASECMP # define stricmp strcasecmp # endif #endif #if HAVE_INTTYPES_H # include #endif #if HAVE_STDINT_H # include typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; #else typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; #endif #if HAVE_SYS_STAT_H # include #endif #if HAVE_SYS_TYPES_H # include #endif #if HAVE_UNISTD_H # include #endif #define _MAX_PATH 255 #if HAVE_ENDIAN_H # include # ifndef __LITTLE_ENDIAN # ifdef _LITTLE_ENDIAN # define __LITTLE_ENDIAN _LITTLE_ENDIAN # define __LITTLE_ENDIAN _LITTLE_ENDIAN # define __BIG_ENDIAN _BIG_ENDIAN # define __PDP_ENDIAN _PDP_ENDIAN # else # error does not define __LITTLE_ENDIAN etc. # endif # endif #else # define __LITTLE_ENDIAN 1234 # define __BIG_ENDIAN 4321 # define __PDP_ENDIAN 3412 # if WORDS_BIGENDIAN # define __BYTE_ORDER __BIG_ENDIAN # else # define __BYTE_ORDER __LITTLE_ENDIAN # endif #endif #else // HAVE_CONFIG_H #include #include #include #include #include #include #include #include #include #include #include #define _MAX_PATH 255 #define stricmp strcasecmp #define _stat stat typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; #endif #endif #ifdef WIN32 #define PATHSEP "\\" #define ALTPATHSEP "/" #else #define PATHSEP "/" #define ALTPATHSEP "\\" #endif // Return type of par2cmdline typedef enum Result { eSuccess = 0, eRepairPossible = 1, // Data files are damaged and there is // enough recovery data available to // repair them. eRepairNotPossible = 2, // Data files are damaged and there is // insufficient recovery data available // to be able to repair them. eInvalidCommandLineArguments = 3, // There was something wrong with the // command line arguments eInsufficientCriticalData = 4, // The PAR2 files did not contain sufficient // information about the data files to be able // to verify them. eRepairFailed = 5, // Repair completed but the data files // still appear to be damaged. eFileIOError = 6, // An error occured when accessing files eLogicError = 7, // In internal error occurred eMemoryError = 8, // Out of memory } Result; #define LONGMULTIPLY // STL includes #include #include #include #include #include #include #include #include #include using namespace std; #ifdef offsetof #undef offsetof #endif #define offsetof(TYPE, MEMBER) ((size_t) ((char*)(&((TYPE *)1)->MEMBER) - (char*)1)) #include "letype.h" // par2cmdline includes #include "galois.h" #include "crc.h" #include "md5.h" #include "par2fileformat.h" #include "commandline.h" #include "reedsolomon.h" #include "diskfile.h" #include "datablock.h" #include "criticalpacket.h" #include "par2creatorsourcefile.h" #include "mainpacket.h" #include "creatorpacket.h" #include "descriptionpacket.h" #include "verificationpacket.h" #include "recoverypacket.h" #include "par2repairersourcefile.h" #include "filechecksummer.h" #include "verificationhashtable.h" #include "par2creator.h" #include "par2repairer.h" #include "par1fileformat.h" #include "par1repairersourcefile.h" #include "par1repairer.h" // Heap checking #ifdef _MSC_VER #define _CRTDBG_MAP_ALLOC #include #define DEBUG_NEW new(_NORMAL_BLOCK, THIS_FILE, __LINE__) #endif #endif // __PARCMDLINE_H__ par2cmdline-0.4/commandline.cpp0000644000000000000000000005535110037517730012212 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif CommandLine::ExtraFile::ExtraFile(void) : filename() , filesize(0) { } CommandLine::ExtraFile::ExtraFile(const CommandLine::ExtraFile &other) : filename(other.filename) , filesize(other.filesize) { } CommandLine::ExtraFile& CommandLine::ExtraFile::operator=(const CommandLine::ExtraFile &other) { filename = other.filename; filesize = other.filesize; return *this; } CommandLine::ExtraFile::ExtraFile(const string &name, u64 size) : filename(name) , filesize(size) { } CommandLine::CommandLine(void) : operation(opNone) , version(verUnknown) , noiselevel(nlUnknown) , blockcount(0) , blocksize(0) , firstblock(0) , recoveryfilescheme(scUnknown) , recoveryfilecount(0) , recoveryblockcount(0) , recoveryblockcountset(false) , redundancy(0) , redundancyset(false) , parfilename() , extrafiles() , totalsourcesize(0) , largestsourcesize(0) , memorylimit(0) { } void CommandLine::usage(void) { cout << "\n" "Usage:\n" "\n" " par2 c(reate) [options] [files] : Create PAR2 files\n" " par2 v(erify) [options] [files] : Verify files using PAR2 file\n" " par2 r(epair) [options] [files] : Repair files using PAR2 files\n" "\n" "You may also leave out the \"c\", \"v\", and \"r\" commands by using \"parcreate\",\n" "\"par2verify\", or \"par2repair\" instead.\n" "\n" "Options:\n" "\n" " -b : Set the Block-Count\n" " -s : Set the Block-Size (Don't use both -b and -s)\n" " -r : Level of Redundancy (%%)\n" " -c : Recovery block count (Don't use both -r and -c)\n" " -f : First Recovery-Block-Number\n" " -u : Uniform recovery file sizes\n" " -l : Limit size of recovery files (Don't use both -u and -l)\n" " -n : Number of recovery files (Don't use both -n and -l)\n" " -m : Memory (in MB) to use\n" " -v [-v]: Be more verbose\n" " -q [-q]: Be more quiet (-q -q gives silence)\n" " -- : Treat all remaining CommandLine as filenames\n" "\n" "If you wish to create par2 files for a single source file, you may leave\n" "out the name of the par2 file from the command line.\n"; } bool CommandLine::Parse(int argc, char *argv[]) { if (argc<1) { return false; } // Split the program name into path and filename string path, name; DiskFile::SplitFilename(argv[0], path, name); argc--; argv++; // Strip ".exe" from the end if (name.size() > 4 && 0 == stricmp(".exe", name.substr(name.length()-4).c_str())) { name = name.substr(0, name.length()-4); } // Check the resulting program name if (0 == stricmp("par2create", name.c_str())) { operation = opCreate; } else if (0 == stricmp("par2verify", name.c_str())) { operation = opVerify; } else if (0 == stricmp("par2repair", name.c_str())) { operation = opRepair; } // Have we determined what operation we want? if (operation == opNone) { if (argc<2) { cerr << "Not enough command line arguments." << endl; return false; } switch (tolower(argv[0][0])) { case 'c': if (argv[0][1] == 0 || 0 == stricmp(argv[0], "create")) operation = opCreate; break; case 'v': if (argv[0][1] == 0 || 0 == stricmp(argv[0], "verify")) operation = opVerify; break; case 'r': if (argv[0][1] == 0 || 0 == stricmp(argv[0], "repair")) operation = opRepair; break; } if (operation == opNone) { cerr << "Invalid operation specified: " << argv[0] << endl; return false; } argc--; argv++; } bool options = true; while (argc>0) { if (argv[0][0]) { if (options && argv[0][0] != '-') options = false; if (options) { switch (tolower(argv[0][1])) { case 'b': // Set the block count { if (operation != opCreate) { cerr << "Cannot specify block count unless creating." << endl; return false; } if (blockcount > 0) { cerr << "Cannot specify block count twice." << endl; return false; } else if (blocksize > 0) { cerr << "Cannot specify both block count and block size." << endl; return false; } char *p = &argv[0][2]; while (blockcount <= 3276 && *p && isdigit(*p)) { blockcount = blockcount * 10 + (*p - '0'); p++; } if (0 == blockcount || blockcount > 32768 || *p) { cerr << "Invalid block count option: " << argv[0] << endl; return false; } } break; case 's': // Set the block size { if (operation != opCreate) { cerr << "Cannot specify block size unless creating." << endl; return false; } if (blocksize > 0) { cerr << "Cannot specify block size twice." << endl; return false; } else if (blockcount > 0) { cerr << "Cannot specify both block count and block size." << endl; return false; } char *p = &argv[0][2]; while (blocksize <= 429496729 && *p && isdigit(*p)) { blocksize = blocksize * 10 + (*p - '0'); p++; } if (*p || blocksize == 0) { cerr << "Invalid block size option: " << argv[0] << endl; return false; } if (blocksize & 3) { cerr << "Block size must be a multiple of 4." << endl; return false; } } break; case 'r': // Set the amount of redundancy required { if (operation != opCreate) { cerr << "Cannot specify redundancy unless creating." << endl; return false; } if (redundancyset) { cerr << "Cannot specify redundancy twice." << endl; return false; } else if (recoveryblockcountset) { cerr << "Cannot specify both redundancy and recovery block count." << endl; return false; } char *p = &argv[0][2]; while (redundancy <= 10 && *p && isdigit(*p)) { redundancy = redundancy * 10 + (*p - '0'); p++; } if (redundancy > 100 || *p) { cerr << "Invalid redundancy option: " << argv[0] << endl; return false; } if (redundancy == 0 && recoveryfilecount > 0) { cerr << "Cannot set redundancy to 0 and file count > 0" << endl; return false; } redundancyset = true; } break; case 'c': // Set the number of recovery blocks to create { if (operation != opCreate) { cerr << "Cannot specify recovery block count unless creating." << endl; return false; } if (recoveryblockcountset) { cerr << "Cannot specify recovery block count twice." << endl; return false; } else if (redundancyset) { cerr << "Cannot specify both recovery block count and redundancy." << endl; return false; } char *p = &argv[0][2]; while (recoveryblockcount <= 32768 && *p && isdigit(*p)) { recoveryblockcount = recoveryblockcount * 10 + (*p - '0'); p++; } if (recoveryblockcount > 32768 || *p) { cerr << "Invalid recoveryblockcount option: " << argv[0] << endl; return false; } if (recoveryblockcount == 0 && recoveryfilecount > 0) { cerr << "Cannot set recoveryblockcount to 0 and file count > 0" << endl; return false; } recoveryblockcountset = true; } break; case 'f': // Specify the First block recovery number { if (operation != opCreate) { cerr << "Cannot specify first block number unless creating." << endl; return false; } if (firstblock > 0) { cerr << "Cannot specify first block twice." << endl; return false; } char *p = &argv[0][2]; while (firstblock <= 3276 && *p && isdigit(*p)) { firstblock = firstblock * 10 + (*p - '0'); p++; } if (firstblock > 32768 || *p) { cerr << "Invalid first block option: " << argv[0] << endl; return false; } } break; case 'u': // Specify uniformly sized recovery files { if (operation != opCreate) { cerr << "Cannot specify uniform files unless creating." << endl; return false; } if (argv[0][2]) { cerr << "Invalid option: " << argv[0] << endl; return false; } if (recoveryfilescheme != scUnknown) { cerr << "Cannot specify two recovery file size schemes." << endl; return false; } recoveryfilescheme = scUniform; } break; case 'l': // Limit the size of the recovery files { if (operation != opCreate) { cerr << "Cannot specify limit files unless creating." << endl; return false; } if (argv[0][2]) { cerr << "Invalid option: " << argv[0] << endl; return false; } if (recoveryfilescheme != scUnknown) { cerr << "Cannot specify two recovery file size schemes." << endl; return false; } if (recoveryfilecount > 0) { cerr << "Cannot specify limited size and number of files at the same time." << endl; return false; } recoveryfilescheme = scLimited; } break; case 'n': // Specify the number of recovery files { if (operation != opCreate) { cerr << "Cannot specify recovery file count unless creating." << endl; return false; } if (recoveryfilecount > 0) { cerr << "Cannot specify recovery file count twice." << endl; return false; } if (redundancyset && redundancy == 0) { cerr << "Cannot set file count when redundancy is set to 0." << endl; return false; } if (recoveryblockcountset && recoveryblockcount == 0) { cerr << "Cannot set file count when recovery block count is set to 0." << endl; return false; } if (recoveryfilescheme == scLimited) { cerr << "Cannot specify limited size and number of files at the same time." << endl; return false; } char *p = &argv[0][2]; while (*p && isdigit(*p)) { recoveryfilecount = recoveryfilecount * 10 + (*p - '0'); p++; } if (recoveryfilecount == 0 || *p) { cerr << "Invalid recovery file count option: " << argv[0] << endl; return false; } } break; case 'm': // Specify how much memory to use for output buffers { if (memorylimit > 0) { cerr << "Cannot specify memory limit twice." << endl; return false; } char *p = &argv[0][2]; while (*p && isdigit(*p)) { memorylimit = memorylimit * 10 + (*p - '0'); p++; } if (memorylimit == 0 || *p) { cerr << "Invalid memory limit option: " << argv[0] << endl; return false; } } break; case 'v': { switch (noiselevel) { case nlUnknown: { if (argv[0][2] == 'v') noiselevel = nlDebug; else noiselevel = nlNoisy; } break; case nlNoisy: case nlDebug: noiselevel = nlDebug; break; default: cerr << "Cannot use both -v and -q." << endl; return false; break; } } break; case 'q': { switch (noiselevel) { case nlUnknown: { if (argv[0][2] == 'q') noiselevel = nlSilent; else noiselevel = nlQuiet; } break; case nlQuiet: case nlSilent: noiselevel = nlSilent; break; default: cerr << "Cannot use both -v and -q." << endl; return false; break; } } break; case '-': { argc--; argv++; options = false; continue; } break; default: { cerr << "Invalid option specified: " << argv[0] << endl; return false; } } } else { list *filenames; // If the argument includes wildcard characters, // search the disk for matching files if (strchr(argv[0], '*') || strchr(argv[0], '?')) { string path; string name; DiskFile::SplitFilename(argv[0], path, name); filenames = DiskFile::FindFiles(path, name); } else { filenames = new list; filenames->push_back(argv[0]); } list::iterator fn = filenames->begin(); while (fn != filenames->end()) { // Convert filename from command line into a full path + filename string filename = DiskFile::GetCanonicalPathname(*fn); // If this is the first file on the command line, then it // is the main PAR2 file. if (parfilename.length() == 0) { // If we are verifying or repairing, the PAR2 file must // already exist if (operation != opCreate) { // Find the last '.' in the filename string::size_type where = filename.find_last_of('.'); if (where != string::npos) { // Get what follows the last '.' string tail = filename.substr(where+1); if (0 == stricmp(tail.c_str(), "par2")) { parfilename = filename; version = verPar2; } else if (0 == stricmp(tail.c_str(), "par") || (tail.size() == 3 && tolower(tail[0]) == 'p' && isdigit(tail[1]) && isdigit(tail[2]))) { parfilename = filename; version = verPar1; } } // If we haven't figured out which version of PAR file we // are using from the file extension, then presumable the // files filename was actually the name of a data file. if (version == verUnknown) { // Check for the existence of a PAR2 of PAR file. if (DiskFile::FileExists(filename + ".par2")) { version = verPar2; parfilename = filename + ".par2"; } else if (DiskFile::FileExists(filename + ".PAR2")) { version = verPar2; parfilename = filename + ".PAR2"; } else if (DiskFile::FileExists(filename + ".par")) { version = verPar1; parfilename = filename + ".par"; } else if (DiskFile::FileExists(filename + ".PAR")) { version = verPar1; parfilename = filename + ".PAR"; } } else { // Does the specified PAR or PAR2 file exist if (!DiskFile::FileExists(filename)) { version = verUnknown; } } if (version == verUnknown) { cerr << "The recovery file does not exist: " << filename << endl; return false; } } else { // We are creating a new file version = verPar2; parfilename = filename; } } else { // All other files must exist if (!DiskFile::FileExists(filename)) { cerr << "The source file does not exist: " << filename << endl; return false; } u64 filesize = DiskFile::GetFileSize(filename); // Ignore all 0 byte files if (filesize > 0) { extrafiles.push_back(ExtraFile(filename, filesize)); // track the total size of the source files and how // big the largest one is. totalsourcesize += filesize; if (largestsourcesize < filesize) largestsourcesize = filesize; } else { cout << "Skipping 0 byte file: " << filename << endl; } } ++fn; } delete filenames; } } argc--; argv++; } if (parfilename.length() == 0) { cerr << "You must specify a Recovery file." << endl; return false; } // Default noise level if (noiselevel == nlUnknown) { noiselevel = nlNormal; } // If we a creating, check the other parameters if (operation == opCreate) { // If no recovery file size scheme is specified then use Variable if (recoveryfilescheme == scUnknown) { recoveryfilescheme = scVariable; } // If neither block count not block size is specified if (blockcount == 0 && blocksize == 0) { // Use a block count of 2000 blockcount = 2000; } // If we are creating, the source files must be given. if (extrafiles.size() == 0) { // Does the par filename include the ".par2" on the end? if (parfilename.length() > 5 && 0 == stricmp(parfilename.substr(parfilename.length()-5, 5).c_str(), ".par2")) { // Yes it does. cerr << "You must specify a list of files when creating." << endl; return false; } else { // No it does not. // In that case check to see if the file exists, and if it does // assume that you wish to create par2 files for it. u64 filesize = 0; if (DiskFile::FileExists(parfilename) && (filesize = DiskFile::GetFileSize(parfilename)) > 0) { extrafiles.push_back(ExtraFile(parfilename, filesize)); // track the total size of the source files and how // big the largest one is. totalsourcesize += filesize; if (largestsourcesize < filesize) largestsourcesize = filesize; } else { // The file does not exist or it is empty. cerr << "You must specify a list of files when creating." << endl; return false; } } } // Strip the ".par2" from the end of the filename of the main PAR2 file. if (parfilename.length() > 5 && 0 == stricmp(parfilename.substr(parfilename.length()-5, 5).c_str(), ".par2")) { parfilename = parfilename.substr(0, parfilename.length()-5); } // Assume a redundancy of 5% if neither redundancy or recoveryblockcount were set. if (!redundancyset && !recoveryblockcountset) { redundancy = 5; } } // Assume a memory limit of 16MB if not specified. if (memorylimit == 0) { #ifdef WIN32 u64 TotalPhysicalMemory = 0; HMODULE hLib = ::LoadLibraryA("kernel32.dll"); if (NULL != hLib) { BOOL (WINAPI *pfn)(LPMEMORYSTATUSEX) = (BOOL (WINAPI*)(LPMEMORYSTATUSEX))::GetProcAddress(hLib, "GlobalMemoryStatusEx"); if (NULL != pfn) { MEMORYSTATUSEX mse; mse.dwLength = sizeof(mse); if (pfn(&mse)) { TotalPhysicalMemory = mse.ullTotalPhys; } } ::FreeLibrary(hLib); } if (TotalPhysicalMemory == 0) { MEMORYSTATUS ms; ::ZeroMemory(&ms, sizeof(ms)); ::GlobalMemoryStatus(&ms); TotalPhysicalMemory = ms.dwTotalPhys; } if (TotalPhysicalMemory == 0) { // Assume 128MB TotalPhysicalMemory = 128 * 1048576; } // Half of total physical memory memorylimit = (size_t)(TotalPhysicalMemory / 1048576 / 2); #else memorylimit = 16; #endif } memorylimit *= 1048576; return true; } par2cmdline-0.4/commandline.h0000644000000000000000000001411310037462211011637 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __COMMANDLINE_H__ #define __COMMANDLINE_H__ // The CommandLine object is responsible for understanding the format // of the command line parameters are parsing the command line to // extract details as to what the user wants to do. class CommandLine { public: CommandLine(void); // Parse the supplied command line arguments. bool Parse(int argc, char *argv[]); // Display details of the correct format for command line parameters. static void usage(void); // What operation will we be carrying out typedef enum { opNone = 0, opCreate, // Create new PAR2 recovery volumes opVerify, // Verify but don't repair damaged data files opRepair // Verify and if possible repair damaged data files } Operation; typedef enum { verUnknown = 0, verPar1, // Processing PAR 1.0 files verPar2 // Processing PAR 2.0 files } Version; typedef enum { scUnknown = 0, scVariable, // Each PAR2 file will have 2x as many blocks as previous scLimited, // Limit PAR2 file size scUniform // All PAR2 files the same size } Scheme; typedef enum { nlUnknown = 0, nlSilent, // Absolutely no output (other than errors) nlQuiet, // Bare minimum of output nlNormal, // Normal level of output nlNoisy, // Lots of output nlDebug // Extra debugging information } NoiseLevel; // Any extra files listed on the command line class ExtraFile { public: ExtraFile(void); ExtraFile(const ExtraFile&); ExtraFile& operator=(const ExtraFile&); ExtraFile(const string &name, u64 size); string FileName(void) const {return filename;} u64 FileSize(void) const {return filesize;} protected: string filename; u64 filesize; }; public: // Accessor functions for the command line parameters CommandLine::Operation GetOperation(void) const {return operation;} CommandLine::Version GetVersion(void) const {return version;} u64 GetBlockSize(void) const {return blocksize;} u32 GetBlockCount(void) const {return blockcount;} u32 GetRedundancy(void) const {return redundancy;} u32 GetFirstRecoveryBlock(void) const {return firstblock;} u32 GetRecoveryFileCount(void) const {return recoveryfilecount;} u32 GetRecoveryBlockCount(void) const {return recoveryblockcount;} CommandLine::Scheme GetRecoveryFileScheme(void) const {return recoveryfilescheme;} size_t GetMemoryLimit(void) const {return memorylimit;} u64 GetLargestSourceSize(void) const {return largestsourcesize;} u64 GetTotalSourceSize(void) const {return totalsourcesize;} CommandLine::NoiseLevel GetNoiseLevel(void) const {return noiselevel;} string GetParFilename(void) const {return parfilename;} const list& GetExtraFiles(void) const {return extrafiles;} protected: Operation operation; // The operation to be carried out. Version version; // What version files will be processed. NoiseLevel noiselevel; // How much display output should there be. u32 blockcount; // How many blocks the source files should // be virtually split into. u64 blocksize; // What virtual block size to use. u32 firstblock; // What the exponent value for the first // recovery block will be. Scheme recoveryfilescheme; // How the the size of the recovery files should // be calculated. u32 recoveryfilecount; // How many recovery files should be created. u32 recoveryblockcount; // How many recovery blocks should be created. bool recoveryblockcountset; // Set if the recoveryblockcount as been specified u32 redundancy; // What percentage of recovery data should // be created. bool redundancyset; // Set if the redundancy has been specified string parfilename; // The name of the PAR2 file to create, or // the name of the first PAR2 file to read // when verifying or repairing. list extrafiles; // The list of other files specified on the // command line. When creating, this will be // the source files, and when verifying or // repairing, this will be additional PAR2 // files or data files to be examined. u64 totalsourcesize; // Total size of the source files. u64 largestsourcesize; // Size of the largest source file. size_t memorylimit; // How much memory is permitted to be used // for the output buffer when creating // or repairing. }; typedef list::const_iterator ExtraFileIterator; #endif // __COMMANDLINE_H__ par2cmdline-0.4/crc.cpp0000644000000000000000000000375707664453143010507 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // The one and only CCITT CRC32 lookup table crc32table ccitttable(0xEDB88320L); // Construct the CRC32 lookup table from the specified polynomial void GenerateCRC32Table(u32 polynomial, u32 (&table)[256]) { for (u32 i = 0; i <= 255 ; i++) { u32 crc = i; for (u32 j = 0; j < 8; j++) { crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); } table[i] = crc; } } // Construct a CRC32 lookup table for windowing void GenerateWindowTable(u64 window, u32 (&target)[256]) { for (u32 i=0; i<=255; i++) { u32 crc = ccitttable.table[i]; for (u64 j=0; j> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc]; } target[i] = crc; } } // Construct the mask value to apply to the CRC when windowing u32 ComputeWindowMask(u64 window) { u32 result = ~0; while (window > 0) { result = CRCUpdateChar(result, (char)0); window--; } result ^= ~0; return result; } par2cmdline-0.4/crc.h0000644000000000000000000000655007664453144010147 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __CRC_H__ #define __CRC_H__ // These global functions are used to compute the CCITT CRC32 checksum of // blocks of data. // The CRC for a block of data may be computed piecemeal be repeatedly // calling CRCUpdateChar, and CRCUpdateBlock. // Given the CRC for a block of data in a buffer, CRCSlideChar may be used // to quickly compute the CRC for the block of data in the buffer that is the // same size but offset one character later in the buffer. // Construct the CRC32 lookup table from the specified polynomial void GenerateCRC32Table(u32 polynomial, u32 (&table)[256]); // A CRC32 lookup table struct crc32table { crc32table(u32 polynomial) { GenerateCRC32Table(polynomial, table); } u32 table[256]; }; // The one and only CCITT CRC32 lookup table extern crc32table ccitttable; // Update the CRC using one character inline u32 CRCUpdateChar(u32 crc, u8 ch) { return ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc ^ ch]; } // Update the CRC using a block of characters in a buffer inline u32 CRCUpdateBlock(u32 crc, size_t length, const void *buffer) { const unsigned char *current = (const unsigned char *)buffer; while (length-- > 0) { crc = ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc ^ (*current++)]; } return crc; } // Update the CRC using a block of 0s. inline u32 CRCUpdateBlock(u32 crc, size_t length) { while (length-- > 0) { crc = ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc]; } return crc; } // Construct a CRC32 lookup table for windowing void GenerateWindowTable(u64 window, u32 (&windowtable)[256]); // Construct the mask value to apply to the CRC when windowing u32 ComputeWindowMask(u64 window); // Slide the CRC along a buffer by one character (removing the old and adding the new). // The new character is added using the main CCITT CRC32 table, and the old character // is removed using the windowtable. inline u32 CRCSlideChar(u32 crc, u8 chNew, u8 chOld, const u32 (&windowtable)[256]) { return ((crc >> 8) & 0x00ffffffL) ^ ccitttable.table[(u8)crc ^ chNew] ^ windowtable[chOld]; } /* char *buffer; u64 window; //... u32 windowtable[256]; GenerateWindowTable(window, windowtable); u32 windowmask = ComputeWindowMask(window); u32 crc = ~0 ^ CRCUpdateBlock(~0, window, buffer); crc = windowmask ^ CRCSlideChar(windowmask ^ crc, buffer[window], buffer[0], windowtable); assert(crc == ~0 ^ CRCUpdateBlock(~0, window, buffer+1)); */ #endif // __CRC_H__ par2cmdline-0.4/creatorpacket.cpp0000644000000000000000000000555607664453145012570 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Construct the creator packet. // The only external information required to complete construction is // the set_id_hash (which is normally computed from information in the // main packet). bool CreatorPacket::Create(const MD5Hash &setid) { string creator = "Created by " PACKAGE " version " VERSION "."; // Allocate a packet just large enough for creator name CREATORPACKET *packet = (CREATORPACKET *)AllocatePacket(sizeof(*packet) + (~3 & (3+(u32)creator.size()))); // Fill in the details the we know packet->header.magic = packet_magic; packet->header.length = packetlength; //packet->header.hash; // Compute shortly packet->header.setid = setid; packet->header.type = creatorpacket_type; // Copy the creator description into the packet memcpy(packet->client, creator.c_str(), creator.size()); // Compute the packet hash MD5Context packetcontext; packetcontext.Update(&packet->header.setid, packetlength - offsetof(PACKET_HEADER, setid)); packetcontext.Final(packet->header.hash); return true; } // Load the packet from disk. bool CreatorPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { // Is the packet long enough if (header.length <= sizeof(CREATORPACKET)) { return false; } // Is the packet too large (what is the longest reasonable creator description) if (header.length - sizeof(CREATORPACKET) > 100000) { return false; } // Allocate the packet (with a little extra so we will have NULLs after the description) CREATORPACKET *packet = (CREATORPACKET *)AllocatePacket((size_t)header.length, 4); packet->header = header; // Load the rest of the packet from disk return diskfile->Read(offset + sizeof(PACKET_HEADER), packet->client, (size_t)packet->header.length - sizeof(PACKET_HEADER)); } par2cmdline-0.4/creatorpacket.h0000644000000000000000000000315407664453145012225 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __CREATORPACKET_H__ #define __CREATORPACKET_H__ // The creator packet records details as to which PAR2 client // created a particular recovery file. // The PAR 2.0 specification requires the presence of a // creator packet, but it is not actually needed for the // verification or recovery of damaged files. class CreatorPacket : public CriticalPacket { public: // Construct the packet CreatorPacket(void) {}; ~CreatorPacket(void) {}; // Create a creator packet for a specified set id hash value bool Create(const MD5Hash &set_id_hash); // Load a creator packet from a specified file bool Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); }; #endif // __CREATORPACKET_H__ par2cmdline-0.4/criticalpacket.cpp0000644000000000000000000000316007664453146012711 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif bool CriticalPacket::WritePacket(DiskFile &diskfile, u64 fileoffset) const { assert(&diskfile != 0 && packetdata != 0 && packetlength != 0); return diskfile.Write(fileoffset, packetdata, packetlength); } void CriticalPacket::FinishPacket(const MD5Hash &setid) { assert(packetdata != 0 && packetlength >= sizeof(PACKET_HEADER)); PACKET_HEADER *header = (PACKET_HEADER*)packetdata; header->setid = setid; MD5Context packetcontext; packetcontext.Update(&header->setid, packetlength - offsetof(PACKET_HEADER, setid)); packetcontext.Final(header->hash); } par2cmdline-0.4/criticalpacket.h0000644000000000000000000000756607664453146012374 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __CRITICALPACKET_H__ #define __CRITICALPACKET_H__ // Base class for main packet, file verification packet, file description packet // and creator packet. // These packets are all small and are held in memory in their entirity class CriticalPacket { public: CriticalPacket(void); ~CriticalPacket(void); public: // Write a copy of the packet to the specified file at the specified offset bool WritePacket(DiskFile &diskfile, u64 fileoffset) const; // Obtain the lenght of the packet. size_t PacketLength(void) const; // Allocate some memory for the packet (plus some extra padding). void* AllocatePacket(size_t length, size_t extra = 0); // Finish a packet (by storing the set_id_hash and then computing the packet_hash). void FinishPacket(const MD5Hash &set_id_hash); protected: u8 *packetdata; size_t packetlength; }; inline CriticalPacket::CriticalPacket(void) { // There is no data initially packetdata = 0; packetlength = 0; } inline CriticalPacket::~CriticalPacket(void) { // Delete the data for the packet delete [] packetdata; } inline size_t CriticalPacket::PacketLength(void) const { return packetlength; } inline void* CriticalPacket::AllocatePacket(size_t length, size_t extra) { // Hey! We can't allocate the packet twice assert(packetlength == 0 && packetdata == 0); // Remember the requested packet length packetlength = length; // Allocate and clear the requested packet length plus the extra. packetdata = new u8[length+extra]; memset(packetdata, 0, length+extra); return packetdata; } // Class used to record the fact that a copy of a particular critical packet // will be written to a particular file at a specific offset. class CriticalPacketEntry { public: CriticalPacketEntry(DiskFile *_diskfile, u64 _offset, const CriticalPacket *_packet) : diskfile(_diskfile) , offset(_offset) , packet(_packet) {} CriticalPacketEntry(void) : diskfile(0) , offset(0) , packet(0) {} CriticalPacketEntry(const CriticalPacketEntry &other) : diskfile(other.diskfile) , offset(other.offset) , packet(other.packet) {} CriticalPacketEntry& operator=(const CriticalPacketEntry &other) { diskfile = other.diskfile; offset = other.offset; packet = other.packet; return *this; } public: // Write the packet to disk. bool WritePacket(void) const; // Obtain the length of the packet. u64 PacketLength(void) const; protected: DiskFile *diskfile; u64 offset; const CriticalPacket *packet; }; inline bool CriticalPacketEntry::WritePacket(void) const { assert(packet != 0 && diskfile != 0); // Tell the packet to write itself to disk return packet->WritePacket(*diskfile, offset); } inline u64 CriticalPacketEntry::PacketLength(void) const { assert(packet != 0); // Ask the packet how big it is. return packet->PacketLength(); } #endif // __CRITICALPACKET_H__ par2cmdline-0.4/datablock.cpp0000644000000000000000000000631407664453147011660 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Open the file associated with the data block if is not already open bool DataBlock::Open(void) { if (diskfile == 0) return false; if (diskfile->IsOpen()) return true; return diskfile->Open(); } // Read some data at a specified position within a data block // into a buffer in memory bool DataBlock::ReadData(u64 position, // Position within the block size_t size, // Size of the memory buffer void *buffer) // Pointer to memory buffer { assert(diskfile != 0); // Check to see if the position from which data is to be read // is within the bounds of the data block if (length > position) { // Compute the file offset and how much data to physically read from disk u64 fileoffset = offset + position; size_t want = (size_t)min((u64)size, length - position); // Read the data from the file into the buffer if (!diskfile->Read(fileoffset, buffer, want)) return false; // If the read extends beyond the end of the data block, // then the rest of the buffer is zeroed. if (want < size) { memset(&((u8*)buffer)[want], 0, size-want); } } else { // Zero the whole buffer memset(buffer, 0, size); } return true; } // Write some data at a specified position within a datablock // from memory to disk bool DataBlock::WriteData(u64 position, // Position within the block size_t size, // Size of the memory buffer const void *buffer, // Pointer to memory buffer size_t &wrote) // Amount actually written { assert(diskfile != 0); wrote = 0; // Check to see if the position from which data is to be written // is within the bounds of the data block if (length > position) { // Compute the file offset and how much data to physically write to disk u64 fileoffset = offset + position; size_t have = (size_t)min((u64)size, length - position); // Write the data from the buffer to disk if (!diskfile->Write(fileoffset, buffer, have)) return false; wrote = have; } return true; } par2cmdline-0.4/datablock.h0000644000000000000000000000651710036507204011307 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __DATABLOCK_H__ #define __DATABLOCK_H__ class DiskFile; // A Data Block is a block of data of a specific length at a specific // offset in a specific file. // It may be either a block of data in a source file from which recovery // data is being computed, a block of recovery data in a recovery file, or // a block in a target file that is being reconstructed. class DataBlock { public: DataBlock(void); ~DataBlock(void); public: // Set the length of the block void SetLength(u64 length); // Set the location of the block void SetLocation(DiskFile *diskfile, u64 offset); void ClearLocation(void); public: // Check to see if the location of the block has been set bool IsSet(void) const; // Which disk file is this data block in DiskFile* GetDiskFile(void) const; // What offset is the block located at u64 GetOffset(void) const; // What is the length of this block u64 GetLength(void) const; public: // Open the disk file if it is not already open (so that it can be read) bool Open(void); // Read some of the data from disk into memory. bool ReadData(u64 position, size_t size, void *buffer); // Write some of the data from memory to disk bool WriteData(u64 position, size_t size, const void *buffer, size_t &wrote); protected: DiskFile *diskfile; // Which disk file is the block associated with u64 offset; // What is the file offset u64 length; // How large is the block }; // Construct the data block inline DataBlock::DataBlock(void) { diskfile = 0; offset = 0; length = 0; } // Destroy the data block inline DataBlock::~DataBlock(void) { } // Set the length of the block inline void DataBlock::SetLength(u64 _length) { length = _length; } // Set the location of the block inline void DataBlock::SetLocation(DiskFile *_diskfile, u64 _offset) { diskfile = _diskfile; offset = _offset; } // Clear the location of the block inline void DataBlock::ClearLocation(void) { diskfile = 0; offset = 0; } // Check to see of the location is known inline bool DataBlock::IsSet(void) const { return (diskfile != 0); } // Which disk file is this data block in inline DiskFile* DataBlock::GetDiskFile(void) const { return diskfile; } // What offset is the block located at inline u64 DataBlock::GetOffset(void) const { return offset; } // What is the length of this block inline u64 DataBlock::GetLength(void) const { return length; } #endif // __DATABLOCK_H__ par2cmdline-0.4/descriptionpacket.cpp0000644000000000000000000000715707664453150013447 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Construct the packet and store the filename and size. bool DescriptionPacket::Create(string filename, u64 filesize) { // Allocate some extra bytes for the packet in memory so that strlen() can // be used on the filename. The extra bytes do not get written to disk. FILEDESCRIPTIONPACKET *packet = (FILEDESCRIPTIONPACKET *)AllocatePacket(sizeof(*packet) + (~3 & (3 + (u32)filename.size())), 4); // Store everything that is currently known in the packet. packet->header.magic = packet_magic; packet->header.length = packetlength; //packet->header.hash; // Not known yet //packet->header.setid; // Not known yet packet->header.type = filedescriptionpacket_type; //packet->fileid; // Not known yet //packet->hashfull; // Not known yet //packet->hash16k; // Not known yet packet->length = filesize; memcpy(packet->name, filename.c_str(), filename.size()); return true; } void DescriptionPacket::Hash16k(const MD5Hash &hash) { ((FILEDESCRIPTIONPACKET *)packetdata)->hash16k = hash; } void DescriptionPacket::HashFull(const MD5Hash &hash) { ((FILEDESCRIPTIONPACKET *)packetdata)->hashfull = hash; } void DescriptionPacket::ComputeFileId(void) { FILEDESCRIPTIONPACKET *packet = ((FILEDESCRIPTIONPACKET *)packetdata); // Compute the fileid from the hash, length, and name fields in the packet. MD5Context context; context.Update(&packet->hash16k, sizeof(FILEDESCRIPTIONPACKET)-offsetof(FILEDESCRIPTIONPACKET,hash16k) +strlen((const char*)packet->name)); context.Final(packet->fileid); } // Load a description packet from a specified file bool DescriptionPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { // Is the packet big enough if (header.length <= sizeof(FILEDESCRIPTIONPACKET)) { return false; } // Is the packet too large (what is the longest permissible filename) if (header.length - sizeof(FILEDESCRIPTIONPACKET) > 100000) { return false; } // Allocate the packet (with a little extra so we will have NULLs after the filename) FILEDESCRIPTIONPACKET *packet = (FILEDESCRIPTIONPACKET *)AllocatePacket((size_t)header.length, 4); packet->header = header; // Read the rest of the packet from disk if (!diskfile->Read(offset + sizeof(PACKET_HEADER), &packet->fileid, (size_t)packet->header.length - sizeof(PACKET_HEADER))) return false; // Are the file and 16k hashes consistent if (packet->length <= 16384 && packet->hash16k != packet->hashfull) { return false; } return true; } par2cmdline-0.4/descriptionpacket.h0000644000000000000000000000651407664453151013111 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __DESCRIPTIONPACKET_H__ #define __DESCRIPTIONPACKET_H__ // The description packet records details about a file (including its name, // size, and the Hash of both the whole file and the first 16k of the file). class DescriptionPacket : public CriticalPacket { public: // Construct the packet DescriptionPacket(void) {}; ~DescriptionPacket(void) {}; public: // Construct the packet and store the filename and size. bool Create(string _filename, u64 _filesize); // Store the computed Hash values in the packet. void Hash16k(const MD5Hash &hash); void HashFull(const MD5Hash &hash); // Compute and return the file id hash from information in the packet void ComputeFileId(void); const MD5Hash& FileId(void) const; // Return the size of the file u64 FileSize(void) const; public: // Load a description packet from a specified file bool Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Return the name of the file string FileName(void) const; // Get the Hash values from the packet const MD5Hash& HashFull(void) const; const MD5Hash& Hash16k(void) const; }; // Get the file id from the packet inline const MD5Hash& DescriptionPacket::FileId(void) const { assert(packetdata != 0); return ((const FILEDESCRIPTIONPACKET*)packetdata)->fileid; } // Get the size of the file from the packet inline u64 DescriptionPacket::FileSize(void) const { assert(packetdata != 0); return ((const FILEDESCRIPTIONPACKET*)packetdata)->length; } // Get the name of the file from the packet // NB whilst the file format does not guarantee that the name will have a NULL // termination character, par2cmdline always allocates a little extra data // and fills it with NULLs to allow the filename to be directly read out of // the packet. inline string DescriptionPacket::FileName(void) const { assert(packetdata != 0); // return (char*)((const FILEDESCRIPTIONPACKET*)packetdata)->name(); return (char*)((const FILEDESCRIPTIONPACKET*)packetdata)->name; } // Get the full file hash value from the packet inline const MD5Hash& DescriptionPacket::HashFull(void) const { assert(packetdata != 0); return ((const FILEDESCRIPTIONPACKET*)packetdata)->hashfull; } // The the hash of the first 16k of the file from the packet inline const MD5Hash& DescriptionPacket::Hash16k(void) const { assert(packetdata != 0); return ((const FILEDESCRIPTIONPACKET*)packetdata)->hash16k; } #endif // __DESCRIPTIONPACKET_H__ par2cmdline-0.4/diskfile.cpp0000644000000000000000000005006210036476261011512 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif #ifdef WIN32 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define OffsetType __int64 #define MaxOffset 0x7fffffffffffffffI64 #define LengthType unsigned int #define MaxLength 0xffffffffUL DiskFile::DiskFile(void) { filename; filesize = 0; offset = 0; hFile = INVALID_HANDLE_VALUE; exists = false; } DiskFile::~DiskFile(void) { if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle(hFile); } // Create new file on disk and make sure that there is enough // space on disk for it. bool DiskFile::Create(string _filename, u64 _filesize) { assert(hFile == INVALID_HANDLE_VALUE); filename = _filename; filesize = _filesize; // Create the file hFile = ::CreateFileA(_filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { DWORD error = ::GetLastError(); cerr << "Could not create \"" << _filename << "\": " << ErrorMessage(error) << endl; return false; } if (filesize > 0) { // Seek to the end of the file LONG lowoffset = ((LONG*)&filesize)[0]; LONG highoffset = ((LONG*)&filesize)[1]; if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, lowoffset, &highoffset, FILE_BEGIN)) { DWORD error = ::GetLastError(); cerr << "Could not set size of \"" << _filename << "\": " << ErrorMessage(error) << endl; ::CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; ::DeleteFile(_filename.c_str()); return false; } // Set the end of the file if (!::SetEndOfFile(hFile)) { DWORD error = ::GetLastError(); cerr << "Could not set size of \"" << _filename << "\": " << ErrorMessage(error) << endl; ::CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; ::DeleteFile(_filename.c_str()); return false; } } offset = filesize; exists = true; return true; } // Write some data to disk bool DiskFile::Write(u64 _offset, const void *buffer, size_t length) { assert(hFile != INVALID_HANDLE_VALUE); if (offset != _offset) { LONG lowoffset = ((LONG*)&_offset)[0]; LONG highoffset = ((LONG*)&_offset)[1]; // Seek to the required offset if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, lowoffset, &highoffset, FILE_BEGIN)) { DWORD error = ::GetLastError(); cerr << "Could not write " << (u64)length << " bytes to \"" << filename << "\" at offset " << _offset << ": " << ErrorMessage(error) << endl; return false; } offset = _offset; } if (length > MaxLength) { cerr << "Could not write " << (u64)length << " bytes to \"" << filename << "\" at offset " << _offset << ": " << "Write too long" << endl; return false; } DWORD write = (LengthType)length; DWORD wrote; // Write the data if (!::WriteFile(hFile, buffer, write, &wrote, NULL)) { DWORD error = ::GetLastError(); cerr << "Could not write " << (u64)length << " bytes to \"" << filename << "\" at offset " << _offset << ": " << ErrorMessage(error) << endl; return false; } offset += length; if (filesize < offset) { filesize = offset; } return true; } // Open the file bool DiskFile::Open(string _filename, u64 _filesize) { assert(hFile == INVALID_HANDLE_VALUE); filename = _filename; filesize = _filesize; hFile = ::CreateFileA(_filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { DWORD error = ::GetLastError(); switch (error) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: break; default: cerr << "Could not open \"" << _filename << "\": " << ErrorMessage(error) << endl; } return false; } offset = 0; exists = true; return true; } // Read some data from disk bool DiskFile::Read(u64 _offset, void *buffer, size_t length) { assert(hFile != INVALID_HANDLE_VALUE); if (offset != _offset) { LONG lowoffset = ((LONG*)&_offset)[0]; LONG highoffset = ((LONG*)&_offset)[1]; // Seek to the required offset if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, lowoffset, &highoffset, FILE_BEGIN)) { DWORD error = ::GetLastError(); cerr << "Could not read " << (u64)length << " bytes from \"" << filename << "\" at offset " << _offset << ": " << ErrorMessage(error) << endl; return false; } offset = _offset; } if (length > MaxLength) { cerr << "Could not read " << (u64)length << " bytes from \"" << filename << "\" at offset " << _offset << ": " << "Read too long" << endl; return false; } DWORD want = (LengthType)length; DWORD got; // Read the data if (!::ReadFile(hFile, buffer, want, &got, NULL)) { DWORD error = ::GetLastError(); cerr << "Could not read " << (u64)length << " bytes from \"" << filename << "\" at offset " << _offset << ": " << ErrorMessage(error) << endl; return false; } offset += length; return true; } void DiskFile::Close(void) { if (hFile != INVALID_HANDLE_VALUE) { ::CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; } } string DiskFile::GetCanonicalPathname(string filename) { char fullname[MAX_PATH]; char *filepart; // Resolve a relative path to a full path int length = ::GetFullPathName(filename.c_str(), sizeof(fullname), fullname, &filepart); if (length <= 0 || sizeof(fullname) < length) return filename; // Make sure the drive letter is upper case. fullname[0] = toupper(fullname[0]); // Translate all /'s to \'s char *current = strchr(fullname, '/'); while (current) { *current++ = '\\'; current = strchr(current, '/'); } // Copy the root directory to the output string string longname(fullname, 3); // Start processing at the first path component current = &fullname[3]; char *limit = &fullname[length]; // Process until we reach the end of the full name while (current < limit) { char *tail; // Find the next \, or the end of the string (tail = strchr(current, '\\')) || (tail = limit); *tail = 0; // Create a wildcard to search for the path string wild = longname + current; WIN32_FIND_DATA finddata; HANDLE hFind = ::FindFirstFile(wild.c_str(), &finddata); if (hFind == INVALID_HANDLE_VALUE) { // If the component was not found then just copy the rest of the path to the // output buffer verbatim. longname += current; break; } ::FindClose(hFind); // Copy the component found to the output longname += finddata.cFileName; current = tail + 1; // If we have not reached the end of the name, add a "\" if (current < limit) longname += '\\'; } return longname; } list* DiskFile::FindFiles(string path, string wildcard) { list *matches = new list; wildcard = path + wildcard; WIN32_FIND_DATA fd; HANDLE h = ::FindFirstFile(wildcard.c_str(), &fd); if (h != INVALID_HANDLE_VALUE) { do { if (0 == (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { matches->push_back(path + fd.cFileName); } } while (::FindNextFile(h, &fd)); ::FindClose(h); } return matches; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// #else // !WIN32 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef HAVE_FSEEKO # define OffsetType off_t # define MaxOffset ((off_t)0x7fffffffffffffffULL) # define fseek fseeko #else # if _FILE_OFFSET_BITS == 64 # define OffsetType unsigned long long # define MaxOffset 0x7fffffffffffffffULL # else # define OffsetType long # define MaxOffset 0x7fffffffUL # endif #endif #define LengthType unsigned int #define MaxLength 0xffffffffUL DiskFile::DiskFile(void) { //filename; filesize = 0; offset = 0; file = 0; exists = false; } DiskFile::~DiskFile(void) { if (file != 0) fclose(file); } // Create new file on disk and make sure that there is enough // space on disk for it. bool DiskFile::Create(string _filename, u64 _filesize) { assert(file == 0); filename = _filename; filesize = _filesize; file = fopen(_filename.c_str(), "wb"); if (file == 0) { cerr << "Could not create: " << _filename << endl; return false; } if (_filesize > (u64)MaxOffset) { cerr << "Requested file size for " << _filename << " is too large." << endl; return false; } if (_filesize > 0) { if (fseek(file, (OffsetType)_filesize-1, SEEK_SET)) { fclose(file); file = 0; ::remove(filename.c_str()); cerr << "Could not set end of file: " << _filename << endl; return false; } if (1 != fwrite(&_filesize, 1, 1, file)) { fclose(file); file = 0; ::remove(filename.c_str()); cerr << "Could not set end of file: " << _filename << endl; return false; } } offset = filesize; exists = true; return true; } // Write some data to disk bool DiskFile::Write(u64 _offset, const void *buffer, size_t length) { assert(file != 0); if (offset != _offset) { if (_offset > (u64)MaxOffset) { cerr << "Could not write " << (u64)length << " bytes to " << filename << " at offset " << _offset << endl; return false; } if (fseek(file, (OffsetType)_offset, SEEK_SET)) { cerr << "Could not write " << (u64)length << " bytes to " << filename << " at offset " << _offset << endl; return false; } offset = _offset; } if (length > MaxLength) { cerr << "Could not write " << (u64)length << " bytes to " << filename << " at offset " << _offset << endl; return false; } if (1 != fwrite(buffer, (LengthType)length, 1, file)) { cerr << "Could not write " << (u64)length << " bytes to " << filename << " at offset " << _offset << endl; return false; } offset += length; if (filesize < offset) { filesize = offset; } return true; } // Open the file bool DiskFile::Open(string _filename, u64 _filesize) { assert(file == 0); filename = _filename; filesize = _filesize; if (_filesize > (u64)MaxOffset) { cerr << "File size for " << _filename << " is too large." << endl; return false; } file = fopen(filename.c_str(), "rb"); if (file == 0) { return false; } offset = 0; exists = true; return true; } // Read some data from disk bool DiskFile::Read(u64 _offset, void *buffer, size_t length) { assert(file != 0); if (offset != _offset) { if (_offset > (u64)MaxOffset) { cerr << "Could not read " << (u64)length << " bytes from " << filename << " at offset " << _offset << endl; return false; } if (fseek(file, (OffsetType)_offset, SEEK_SET)) { cerr << "Could not read " << (u64)length << " bytes from " << filename << " at offset " << _offset << endl; return false; } offset = _offset; } if (length > MaxLength) { cerr << "Could not read " << (u64)length << " bytes from " << filename << " at offset " << _offset << endl; return false; } if (1 != fread(buffer, (LengthType)length, 1, file)) { cerr << "Could not read " << (u64)length << " bytes from " << filename << " at offset " << _offset << endl; return false; } offset += length; return true; } void DiskFile::Close(void) { if (file != 0) { fclose(file); file = 0; } } // Attempt to get the full pathname of the file string DiskFile::GetCanonicalPathname(string filename) { // Is the supplied path already an absolute one if (filename.size() == 0 || filename[0] == '/') return filename; // Get the current directory char curdir[1000]; if (0 == getcwd(curdir, sizeof(curdir))) { return filename; } // Allocate a work buffer and copy the resulting full path into it. char *work = new char[strlen(curdir) + filename.size() + 2]; strcpy(work, curdir); if (work[strlen(work)-1] != '/') strcat(work, "/"); strcat(work, filename.c_str()); char *in = work; char *out = work; while (*in) { if (*in == '/') { if (in[1] == '.' && in[2] == '/') { // skip the input past /./ in += 2; } else if (in[1] == '.' && in[2] == '.' && in[3] == '/') { // backtrack the output if /../ was found on the input in += 3; if (out > work) { do { out--; } while (out > work && *out != '/'); } } else { *out++ = *in++; } } else { *out++ = *in++; } } *out = 0; string result = work; delete [] work; return result; } list* DiskFile::FindFiles(string path, string wildcard) { list *matches = new list; string::size_type where; if ((where = wildcard.find_first_of('*')) != string::npos || (where = wildcard.find_first_of('?')) != string::npos) { string front = wildcard.substr(0, where); bool multiple = wildcard[where] == '*'; string back = wildcard.substr(where+1); DIR *dirp = opendir(path.c_str()); if (dirp != 0) { struct dirent *d; while ((d = readdir(dirp)) != 0) { string name = d->d_name; if (name == "." || name == "..") continue; if (multiple) { if (name.size() >= wildcard.size() && name.substr(0, where) == front && name.substr(name.size()-back.size()) == back) { matches->push_back(path + name); } } else { if (name.size() == wildcard.size()) { string::const_iterator pw = wildcard.begin(); string::const_iterator pn = name.begin(); while (pw != wildcard.end()) { if (*pw != '?' && *pw != *pn) break; ++pw; ++pn; } if (pw == wildcard.end()) { matches->push_back(path + name); } } } } closedir(dirp); } } else { struct stat st; string fn = path + wildcard; if (stat(fn.c_str(), &st) == 0) { matches->push_back(path + wildcard); } } return matches; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// #endif bool DiskFile::Open(void) { string _filename = filename; return Open(_filename); } bool DiskFile::Open(string _filename) { return Open(_filename, GetFileSize(_filename)); } // Delete the file bool DiskFile::Delete(void) { #ifdef WIN32 assert(hFile == INVALID_HANDLE_VALUE); #else assert(file == 0); #endif if (filename.size() > 0 && 0 == unlink(filename.c_str())) { return true; } else { cerr << "Cannot delete " << filename << endl; return false; } } //string DiskFile::GetPathFromFilename(string filename) //{ // string::size_type where; // // if (string::npos != (where = filename.find_last_of('/')) || // string::npos != (where = filename.find_last_of('\\'))) // { // return filename.substr(0, where+1); // } // else // { // return "." PATHSEP; // } //} void DiskFile::SplitFilename(string filename, string &path, string &name) { string::size_type where; if (string::npos != (where = filename.find_last_of('/')) || string::npos != (where = filename.find_last_of('\\'))) { path = filename.substr(0, where+1); name = filename.substr(where+1); } else { path = "." PATHSEP; name = filename; } } bool DiskFile::FileExists(string filename) { struct stat st; return ((0 == stat(filename.c_str(), &st)) && (0 != (st.st_mode & S_IFREG))); } u64 DiskFile::GetFileSize(string filename) { struct stat st; if ((0 == stat(filename.c_str(), &st)) && (0 != (st.st_mode & S_IFREG))) { return st.st_size; } else { return 0; } } // Take a filename from a PAR2 file and replace any characters // which would be illegal for a file on disk string DiskFile::TranslateFilename(string filename) { string result; string::iterator p = filename.begin(); while (p != filename.end()) { unsigned char ch = *p; bool ok = true; #ifdef WIN32 if (ch < 32) { ok = false; } else { switch (ch) { case '"': case '*': case '/': case ':': case '<': case '>': case '?': case '\\': case '|': ok = false; } } #else if (ch < 32) { ok = false; } else { switch (ch) { case '/': ok = false; } } #endif if (ok) { result += ch; } else { // convert problem characters to hex result += ((ch >> 4) < 10) ? (ch >> 4) + '0' : (ch >> 4) + 'A'-10; result += ((ch & 0xf) < 10) ? (ch & 0xf) + '0' : (ch & 0xf) + 'A'-10; } ++p; } return result; } bool DiskFile::Rename(void) { char newname[_MAX_PATH+1]; u32 index = 0; struct stat st; do { int length = snprintf(newname, _MAX_PATH, "%s.%d", filename.c_str(), ++index); if (length < 0) { cerr << filename << " cannot be renamed." << endl; return false; } newname[length] = 0; } while (stat(newname, &st) == 0); return Rename(newname); } bool DiskFile::Rename(string _filename) { #ifdef WIN32 assert(hFile == INVALID_HANDLE_VALUE); #else assert(file == 0); #endif if (::rename(filename.c_str(), _filename.c_str()) == 0) { filename = _filename; return true; } else { cerr << filename << " cannot be renamed to " << _filename << endl; return false; } } #ifdef WIN32 string DiskFile::ErrorMessage(DWORD error) { string result; LPVOID lpMsgBuf; if (::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&lpMsgBuf, 0, NULL)) { result = (char*)lpMsgBuf; LocalFree(lpMsgBuf); } else { char message[40]; _snprintf(message, sizeof(message), "Unknown error code (%d)", error); result = message; } return result; } #endif DiskFileMap::DiskFileMap(void) { } DiskFileMap::~DiskFileMap(void) { map::iterator fi = diskfilemap.begin(); while (fi != diskfilemap.end()) { delete (*fi).second; ++fi; } } bool DiskFileMap::Insert(DiskFile *diskfile) { string filename = diskfile->FileName(); assert(filename.length() != 0); pair::const_iterator,bool> location = diskfilemap.insert(pair(filename, diskfile)); return location.second; } void DiskFileMap::Remove(DiskFile *diskfile) { string filename = diskfile->FileName(); assert(filename.length() != 0); diskfilemap.erase(filename); } DiskFile* DiskFileMap::Find(string filename) const { assert(filename.length() != 0); map::const_iterator f = diskfilemap.find(filename); return (f != diskfilemap.end()) ? f->second : 0; } par2cmdline-0.4/diskfile.h0000644000000000000000000000643007664453152011166 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __DISKFILE_H__ #define __DISKFILE_H__ // A disk file can be any type of file that par2cmdline needs // to read or write data from or to. class DiskFile { public: DiskFile(void); ~DiskFile(void); // Create a file and set its length bool Create(string filename, u64 filesize); // Write some data to the file bool Write(u64 offset, const void *buffer, size_t length); // Open the file bool Open(void); bool Open(string filename); bool Open(string filename, u64 filesize); // Check to see if the file is open #ifdef WIN32 bool IsOpen(void) const {return hFile != INVALID_HANDLE_VALUE;} #else bool IsOpen(void) const {return file != 0;} #endif // Read some data from the file bool Read(u64 offset, void *buffer, size_t length); // Close the file void Close(void); // Get the size of the file u64 FileSize(void) const {return filesize;} // Get the name of the file string FileName(void) const {return filename;} // Does the file exist bool Exists(void) const {return exists;} // Rename the file bool Rename(void); // Pick a filename automatically bool Rename(string filename); // Delete the file bool Delete(void); public: static string GetCanonicalPathname(string filename); static void SplitFilename(string filename, string &path, string &name); static string TranslateFilename(string filename); static bool FileExists(string filename); static u64 GetFileSize(string filename); // Search the specified path for files which match the specified wildcard // and return their names in a list. static list* FindFiles(string path, string wildcard); protected: string filename; u64 filesize; // OS file handle #ifdef WIN32 HANDLE hFile; #else FILE *file; #endif // Current offset within the file u64 offset; // Does the file exist bool exists; protected: #ifdef WIN32 static string ErrorMessage(DWORD error); #endif }; // This class keeps track of which DiskFile objects exist // and which file on disk they are associated with. // It is used to avoid a file being processed twice. class DiskFileMap { public: DiskFileMap(void); ~DiskFileMap(void); bool Insert(DiskFile *diskfile); void Remove(DiskFile *diskfile); DiskFile* Find(string filename) const; protected: map diskfilemap; // Map from filename to DiskFile }; #endif // __DISKFILE_H__ par2cmdline-0.4/filechecksummer.cpp0000644000000000000000000001351607664453153013101 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Construct the checksummer and allocate buffers FileCheckSummer::FileCheckSummer(DiskFile *_diskfile, u64 _blocksize, const u32 (&_windowtable)[256], u32 _windowmask) : diskfile(_diskfile) , blocksize(_blocksize) , windowtable(_windowtable) , windowmask(_windowmask) { buffer = new char[(size_t)blocksize*2]; filesize = diskfile->FileSize(); currentoffset = 0; } FileCheckSummer::~FileCheckSummer(void) { delete [] buffer; } // Start reading the file at the beginning bool FileCheckSummer::Start(void) { currentoffset = readoffset = 0; tailpointer = outpointer = buffer; inpointer = &buffer[blocksize]; // Fill the buffer with new data if (!Fill()) return false; // Compute the checksum for the block checksum = ~0 ^ CRCUpdateBlock(~0, (size_t)blocksize, buffer); return true; } // Jump ahead bool FileCheckSummer::Jump(u64 distance) { // Are we already at the end of the file if (currentoffset >= filesize) return false; // Special distances if (distance == 0) return false; if (distance == 1) return Step(); // Not allowed to jump more than one block assert(distance <= blocksize); if (distance > blocksize) distance = blocksize; // Advance the current offset and check if we have reached the end of the file currentoffset += distance; if (currentoffset >= filesize) { currentoffset = filesize; tailpointer = outpointer = buffer; memset(buffer, 0, (size_t)blocksize); checksum = 0; return true; } // Move past the data being discarded outpointer += distance; assert(outpointer <= tailpointer); // Is there any data left in the buffer that we are keeping size_t keep = tailpointer - outpointer; if (keep > 0) { // Move it back to the start of the buffer memmove(buffer, outpointer, keep); tailpointer = &buffer[keep]; } else { tailpointer = buffer; } outpointer = buffer; inpointer = &buffer[blocksize]; if (!Fill()) return false; // Compute the checksum for the block checksum = ~0 ^ CRCUpdateBlock(~0, (size_t)blocksize, buffer); return true; } // Fill the buffer from disk bool FileCheckSummer::Fill(void) { // Have we already reached the end of the file if (readoffset >= filesize) return true; // How much data can we read into the buffer size_t want = (size_t)min(filesize-readoffset, (u64)(&buffer[2*blocksize]-tailpointer)); if (want > 0) { // Read data if (!diskfile->Read(readoffset, tailpointer, want)) return false; UpdateHashes(readoffset, tailpointer, want); readoffset += want; tailpointer += want; } // Did we fill the buffer want = &buffer[2*blocksize] - tailpointer; if (want > 0) { // Blank the rest of the buffer memset(tailpointer, 0, want); } return true; } // Update the full file hash and the 16k hash using the new data void FileCheckSummer::UpdateHashes(u64 offset, const void *buffer, size_t length) { // Are we already beyond the first 16k if (offset >= 16384) { contextfull.Update(buffer, length); } // Would we reach the 16k mark else if (offset+length >= 16384) { // Finish the 16k hash size_t first = (size_t)(16384-offset); context16k.Update(buffer, first); // Continue with the full hash contextfull = context16k; // Do we go beyond the 16k mark if (offset+length > 16384) { contextfull.Update(&((const char*)buffer)[first], length-first); } } else { context16k.Update(buffer, length); } } // Return the full file hash and the 16k file hash void FileCheckSummer::GetFileHashes(MD5Hash &hashfull, MD5Hash &hash16k) const { // Compute the hash of the first 16k MD5Context context = context16k; context.Final(hash16k); // Is the file smaller than 16k if (filesize < 16384) { // The hashes are the same hashfull = hash16k; } else { // Compute the hash of the full file context = contextfull; context.Final(hashfull); } } // Compute and return the current hash MD5Hash FileCheckSummer::Hash(void) { MD5Context context; context.Update(outpointer, (size_t)blocksize); MD5Hash hash; context.Final(hash); return hash; } u32 FileCheckSummer::ShortChecksum(u64 blocklength) { u32 crc = CRCUpdateBlock(~0, (size_t)blocklength, outpointer); if (blocksize > blocklength) { crc = CRCUpdateBlock(crc, (size_t)(blocksize-blocklength)); } crc ^= ~0; return crc; } MD5Hash FileCheckSummer::ShortHash(u64 blocklength) { MD5Context context; context.Update(outpointer, (size_t)blocklength); if (blocksize > blocklength) { context.Update((size_t)(blocksize-blocklength)); } // Get the hash value MD5Hash hash; context.Final(hash); return hash; } par2cmdline-0.4/filechecksummer.h0000644000000000000000000001213207664453154012540 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __FILECHECKSUMMER_H__ #define __FILECHECKSUMMER_H__ // This source file defines the FileCheckSummer object which is used // when scanning a data file to find blocks of undamaged data. // // The object uses a "window" into the data file and slides that window // along the file computing the CRC of the data in that window as it // goes. If the computed CRC matches the value for a block of data // from a target data file, then the MD5 Hash value is also computed // and compared with the value for that block of data. When a match // has been confirmed, the object jumps forward to where the next // block of data is expected to start. Whilst the file is being scanned // the object also computes the MD5 Hash of the whole file and of // the first 16k of the file for later tests. class FileCheckSummer { public: FileCheckSummer(DiskFile *diskfile, u64 blocksize, const u32 (&windowtable)[256], u32 windowmask); ~FileCheckSummer(void); // Start reading the file at the beginning bool Start(void); // Jump ahead the specified distance bool Jump(u64 distance); // Step forward one byte bool Step(void); // Return the current checksum u32 Checksum(void) const; // Compute and return the current hash MD5Hash Hash(void); // Compute short values of checksum and hash u32 ShortChecksum(u64 blocklength); MD5Hash ShortHash(u64 blocklength); // Do we have less than a full block of data bool ShortBlock(void) const; u64 BlockLength(void) const; // Return the current file offset u64 Offset(void) const; // Return the full file hash and the 16k file hash void GetFileHashes(MD5Hash &hashfull, MD5Hash &hash16k) const; // Which disk file is this const DiskFile* GetDiskFile(void) const {return diskfile;} protected: DiskFile *diskfile; u64 blocksize; const u32 (&windowtable)[256]; u32 windowmask; u64 filesize; u64 currentoffset; // file offset for current window position char *buffer; // buffer for reading from the file char *outpointer; // position in buffer of scan window char *inpointer; // &outpointer[blocksize]; char *tailpointer; // after last valid data in buffer // File offset for next read u64 readoffset; // The current checksum u32 checksum; // MD5 hash of whole file and of first 16k MD5Context contextfull; MD5Context context16k; protected: //void ComputeCurrentCRC(void); void UpdateHashes(u64 offset, const void *buffer, size_t length); //// Fill the buffers with more data from disk bool Fill(void); }; // Return the current checksum inline u32 FileCheckSummer::Checksum(void) const { return checksum; } // Return the current block length inline u64 FileCheckSummer::BlockLength(void) const { return min(blocksize, filesize-currentoffset); } // Return whether or not the current block is a short one. inline bool FileCheckSummer::ShortBlock(void) const { return BlockLength() < blocksize; } // Return the current file offset inline u64 FileCheckSummer::Offset(void) const { return currentoffset; } // Step forward one byte inline bool FileCheckSummer::Step(void) { // Are we already at the end of the file if (currentoffset >= filesize) return false; // Advance the file offset and check to see if // we have reached the end of the file if (++currentoffset >= filesize) { currentoffset = filesize; tailpointer = outpointer = buffer; memset(buffer, 0, (size_t)blocksize); checksum = 0; return true; } // Get the incoming and outgoing characters char inch = *inpointer++; char outch = *outpointer++; // Update the checksum checksum = windowmask ^ CRCSlideChar(windowmask ^ checksum, inch, outch, windowtable); // Can the window slide further if (outpointer < &buffer[blocksize]) return true; assert(outpointer == &buffer[blocksize]); // Copy the data back to the beginning of the buffer memmove(buffer, outpointer, (size_t)blocksize); inpointer = outpointer; outpointer = buffer; tailpointer -= blocksize; // Fill the rest of the buffer return Fill(); } #endif // __FILECHECKSUMMER_H__ par2cmdline-0.4/galois.cpp0000644000000000000000000000206407664453154011206 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif par2cmdline-0.4/galois.h0000755000000000000000000002140107711432620010636 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __GALOIS_H__ #define __GALOIS_H__ template class GaloisTable; template class Galois; template class GaloisLongMultiplyTable; // This source file defines the Galois object for carrying out // arithmetic in GF(2^16) using the generator 0x1100B. // Also defined are the GaloisTable object (which contains log and // anti log tables for use in multiplication and division), and // the GaloisLongMultiplyTable object (which contains tables for // carrying out multiplation of 16-bit galois numbers 8 bits at a time). template class GaloisTable { public: typedef valuetype ValueType; GaloisTable(void); enum { Bits = bits, Count = 1< class Galois { public: typedef valuetype ValueType; // Basic constructors Galois(void) {}; Galois(ValueType v); // Copy and assignment Galois(const Galois &right) {value = right.value;} Galois& operator = (const Galois &right) { value = right.value; return *this;} // Addition Galois operator + (const Galois &right) const { return (value ^ right.value); } Galois& operator += (const Galois &right) { value ^= right.value; return *this;} // Subtraction Galois operator - (const Galois &right) const { return (value ^ right.value); } Galois& operator -= (const Galois &right) { value ^= right.value; return *this;} // Multiplication Galois operator * (const Galois &right) const; Galois& operator *= (const Galois &right); // Division Galois operator / (const Galois &right) const; Galois& operator /= (const Galois &right); // Power Galois pow(unsigned int right) const; Galois operator ^ (unsigned int right) const; Galois& operator ^= (unsigned int right); // Cast to value and value access operator ValueType(void) const {return value;} ValueType Value(void) const {return value;} // Direct log and antilog ValueType Log(void) const; ValueType ALog(void) const; enum { Bits = GaloisTable::Bits, Count = GaloisTable::Count, Limit = GaloisTable::Limit, }; protected: ValueType value; static GaloisTable table; }; #ifdef LONGMULTIPLY template class GaloisLongMultiplyTable { public: GaloisLongMultiplyTable(void); typedef g G; enum { Bytes = ((G::Bits + 7) >> 3), Count = ((Bytes * (Bytes+1)) / 2), }; G tables[Count * 256 * 256]; }; #endif // Construct the log and antilog tables from the generator template inline GaloisTable::GaloisTable(void) { u32 b = 1; for (u32 l=0; l GaloisTable Galois::table; template inline Galois::Galois(typename Galois::ValueType v) { value = v; } template inline Galois Galois::operator * (const Galois &right) const { if (value == 0 || right.value == 0) return 0; unsigned int sum = table.log[value] + table.log[right.value]; if (sum >= Limit) { return table.antilog[sum-Limit]; } else { return table.antilog[sum]; } } template inline Galois& Galois::operator *= (const Galois &right) { if (value == 0 || right.value == 0) { value = 0; } else { unsigned int sum = table.log[value] + table.log[right.value]; if (sum >= Limit) { value = table.antilog[sum-Limit]; } else { value = table.antilog[sum]; } } return *this; } template inline Galois Galois::operator / (const Galois &right) const { if (value == 0) return 0; assert(right.value != 0); if (right.value == 0) {return 0;} // Division by 0! int sum = table.log[value] - table.log[right.value]; if (sum < 0) { return table.antilog[sum+Limit]; } else { return table.antilog[sum]; } } template inline Galois& Galois::operator /= (const Galois &right) { if (value == 0) return *this; assert(right.value != 0); if (right.value == 0) {return *this;} // Division by 0! int sum = table.log[value] - table.log[right.value]; if (sum < 0) { value = table.antilog[sum+Limit]; } else { value = table.antilog[sum]; } return *this; } template inline Galois Galois::pow(unsigned int right) const { if (right == 0) return 1; if (value == 0) return 0; unsigned int sum = table.log[value] * right; sum = (sum >> Bits) + (sum & Limit); if (sum >= Limit) { return table.antilog[sum-Limit]; } else { return table.antilog[sum]; } } template inline Galois Galois::operator ^ (unsigned int right) const { if (right == 0) return 1; if (value == 0) return 0; unsigned int sum = table.log[value] * right; sum = (sum >> Bits) + (sum & Limit); if (sum >= Limit) { return table.antilog[sum-Limit]; } else { return table.antilog[sum]; } } template inline Galois& Galois::operator ^= (unsigned int right) { if (right == 1) {value = 1; return *this;} if (value == 0) return *this; unsigned int sum = table.log[value] * right; sum = (sum >> Bits) + (sum & Limit); if (sum >= Limit) { value = table.antilog[sum-Limit]; } else { value = table.antilog[sum]; } return *this; } template inline valuetype Galois::Log(void) const { return table.log[value]; } template inline valuetype Galois::ALog(void) const { return table.antilog[value]; } #ifdef LONGMULTIPLY template inline GaloisLongMultiplyTable::GaloisLongMultiplyTable(void) { G *table = tables; for (unsigned int i=0; i Galois8; typedef Galois<16,0x1100B,u16> Galois16; #endif // __GALOIS_H__ par2cmdline-0.4/letype.h0000644000000000000000000001260507664453155010702 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __LETYPE_H__ #define __LETYPE_H__ #if __BYTE_ORDER == __LITTLE_ENDIAN typedef u16 leu16; typedef u32 leu32; typedef u64 leu64; #else class leu16 { public: leu16(void); leu16(const leu16 &other); leu16& operator=(const leu16 &other); leu16(const u16 &other); leu16& operator=(const u16 &other); operator u16(void) const; protected: u16 value; }; inline leu16::leu16(void) { } inline leu16::leu16(const leu16 &other) : value(other.value) { } inline leu16& leu16::operator =(const leu16 &other) { value = other.value; return *this; } inline leu16::leu16(const u16 &other) { ((unsigned char*)&value)[0] = (unsigned char)((other >> 0) & 0xff); ((unsigned char*)&value)[1] = (unsigned char)((other >> 8) & 0xff); } inline leu16& leu16::operator=(const u16 &other) { ((unsigned char*)&value)[0] = (unsigned char)((other >> 0) & 0xff); ((unsigned char*)&value)[1] = (unsigned char)((other >> 8) & 0xff); return *this; } inline leu16::operator u16(void) const { return ((unsigned char*)&value)[0] << 0 | ((unsigned char*)&value)[1] << 8; } class leu32 { public: leu32(void); leu32(const leu32 &other); leu32& operator=(const leu32 &other); leu32(const u32 &other); leu32& operator=(const u32 &other); operator u32(void) const; protected: u32 value; }; inline leu32::leu32(void) { } inline leu32::leu32(const leu32 &other) : value(other.value) { } inline leu32& leu32::operator =(const leu32 &other) { value = other.value; return *this; } inline leu32::leu32(const u32 &other) { ((unsigned char*)&value)[0] = (unsigned char)((other >> 0) & 0xff); ((unsigned char*)&value)[1] = (unsigned char)((other >> 8) & 0xff); ((unsigned char*)&value)[2] = (unsigned char)((other >> 16) & 0xff); ((unsigned char*)&value)[3] = (unsigned char)((other >> 24) & 0xff); } inline leu32& leu32::operator=(const u32 &other) { ((unsigned char*)&value)[0] = (unsigned char)((other >> 0) & 0xff); ((unsigned char*)&value)[1] = (unsigned char)((other >> 8) & 0xff); ((unsigned char*)&value)[2] = (unsigned char)((other >> 16) & 0xff); ((unsigned char*)&value)[3] = (unsigned char)((other >> 24) & 0xff); return *this; } inline leu32::operator u32(void) const { return ((unsigned char*)&value)[0] << 0 | ((unsigned char*)&value)[1] << 8 | ((unsigned char*)&value)[2] << 16 | ((unsigned char*)&value)[3] << 24; } class leu64 { public: leu64(void); leu64(const leu64 &other); leu64& operator=(const leu64 &other); leu64(const u64 &other); leu64& operator=(const u64 &other); operator u64(void) const; protected: u64 value; }; inline leu64::leu64(void) { } inline leu64::leu64(const leu64 &other) : value(other.value) { } inline leu64& leu64::operator =(const leu64 &other) { value = other.value; return *this; } inline leu64::leu64(const u64 &other) { ((unsigned char*)&value)[0] = (unsigned char)((other >> 0) & 0xff); ((unsigned char*)&value)[1] = (unsigned char)((other >> 8) & 0xff); ((unsigned char*)&value)[2] = (unsigned char)((other >> 16) & 0xff); ((unsigned char*)&value)[3] = (unsigned char)((other >> 24) & 0xff); ((unsigned char*)&value)[4] = (unsigned char)((other >> 32) & 0xff); ((unsigned char*)&value)[5] = (unsigned char)((other >> 40) & 0xff); ((unsigned char*)&value)[6] = (unsigned char)((other >> 48) & 0xff); ((unsigned char*)&value)[7] = (unsigned char)((other >> 56) & 0xff); } inline leu64& leu64::operator=(const u64 &other) { ((unsigned char*)&value)[0] = (unsigned char)((other >> 0) & 0xff); ((unsigned char*)&value)[1] = (unsigned char)((other >> 8) & 0xff); ((unsigned char*)&value)[2] = (unsigned char)((other >> 16) & 0xff); ((unsigned char*)&value)[3] = (unsigned char)((other >> 24) & 0xff); ((unsigned char*)&value)[4] = (unsigned char)((other >> 32) & 0xff); ((unsigned char*)&value)[5] = (unsigned char)((other >> 40) & 0xff); ((unsigned char*)&value)[6] = (unsigned char)((other >> 48) & 0xff); ((unsigned char*)&value)[7] = (unsigned char)((other >> 56) & 0xff); return *this; } inline leu64::operator u64(void) const { return (u64)(((unsigned char*)&value)[0]) << 0 | (u64)(((unsigned char*)&value)[1]) << 8 | (u64)(((unsigned char*)&value)[2]) << 16 | (u64)(((unsigned char*)&value)[3]) << 24 | (u64)(((unsigned char*)&value)[4]) << 32 | (u64)(((unsigned char*)&value)[5]) << 40 | (u64)(((unsigned char*)&value)[6]) << 48 | (u64)(((unsigned char*)&value)[7]) << 56; } #endif #endif // __LETYPE_H__ par2cmdline-0.4/mainpacket.cpp0000644000000000000000000001007307664453156012045 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Construct the main packet from the source files and the block size bool MainPacket::Create(vector &sourcefiles, u64 _blocksize) { recoverablefilecount = totalfilecount =(u32)sourcefiles.size(); blocksize = _blocksize; // Allocate memory for the main packet with enough fileid entries MAINPACKET *packet = (MAINPACKET *)AllocatePacket(sizeof(MAINPACKET) + totalfilecount * sizeof(MD5Hash)); // Record the details we already know in the packet packet->header.magic = packet_magic; packet->header.length = packetlength; //packet->header.hash; // Compute shortly //packet->header.setid; // Compute shortly packet->header.type = mainpacket_type; packet->blocksize = _blocksize; packet->recoverablefilecount = totalfilecount; //packet->fileid; // Compute shortly // Sort the source files according to their fileid values if (totalfilecount > 1) { sort(sourcefiles.begin(), sourcefiles.end(), Par2CreatorSourceFile::CompareLess); } // Store the fileid values in the main packet vector::const_iterator sourcefile; MD5Hash *hash; for ((sourcefile=sourcefiles.begin()),(hash=packet->fileid); sourcefile!=sourcefiles.end(); ++sourcefile, ++hash) { *hash = (*sourcefile)->FileId(); } // Compute the set_id_hash MD5Context setidcontext; setidcontext.Update(&packet->blocksize, packetlength - offsetof(MAINPACKET, blocksize)); setidcontext.Final(packet->header.setid); // Compute the packet_hash MD5Context packetcontext; packetcontext.Update(&packet->header.setid, packetlength - offsetof(MAINPACKET, header.setid)); packetcontext.Final(packet->header.hash); return true; } // Load a main packet from a specified file bool MainPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { // Is the packet large enough if (header.length < sizeof(MAINPACKET)) { return false; } // Is there a whole number of fileid values if (0 < (header.length - sizeof(MAINPACKET)) % sizeof(MD5Hash)) { return false; } // Is the packet too large if (header.length > sizeof(MAINPACKET) + 32768 * sizeof(MD5Hash)) { return false; } // Compute the total number of entries in the fileid array totalfilecount = (u32)(((size_t)header.length - sizeof(MAINPACKET)) / sizeof(MD5Hash)); MAINPACKET *packet = (MAINPACKET *)AllocatePacket((size_t)header.length); packet->header = header; // Read the rest of the packet from disk if (!diskfile->Read(offset + sizeof(PACKET_HEADER), &packet->blocksize, (size_t)packet->header.length - sizeof(PACKET_HEADER))) return false; // Does the packet have enough fileid values recoverablefilecount = packet->recoverablefilecount; if (recoverablefilecount > totalfilecount) { return false; } // Is the block size valid blocksize = packet->blocksize; if (blocksize == 0 || (blocksize & 3) != 0) { return false; } return true; } par2cmdline-0.4/mainpacket.h0000644000000000000000000000566507664453157011526 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __MAINPACKET_H__ #define __MAINPACKET_H__ // The main packet ties all other critical packets together. // It specifies the block size to use for both verification of // files and for the Reed Solomon computation. // It also specifies how many of the source files are repairable // and in what order they should be processed. class MainPacket : public CriticalPacket { public: // Construct the packet MainPacket(void) {}; ~MainPacket(void) {}; public: // Construct the main packet from the source file list and block size. // "sourcefiles" will be sorted base on their FileId value. bool Create(vector &sourcefiles, u64 _blocksize); // Load a main packet from a specified file bool Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); public: // Get the set id. const MD5Hash& SetId(void) const; // Get the block size. u64 BlockSize(void) const; // Get the file counts. u32 RecoverableFileCount(void) const; u32 TotalFileCount(void) const; // Get the fileid of one file const MD5Hash& FileId(u32 filenumber) const; protected: u64 blocksize; u32 totalfilecount; u32 recoverablefilecount; }; // Get the data block size inline u64 MainPacket::BlockSize(void) const { assert(packetdata != 0); return blocksize; } // Get the number of recoverable files inline u32 MainPacket::RecoverableFileCount(void) const { assert(packetdata != 0); return recoverablefilecount; } // Get the total number of files inline u32 MainPacket::TotalFileCount(void) const { assert(packetdata != 0); return totalfilecount; } // Get the file id hash of one of the files inline const MD5Hash& MainPacket::FileId(u32 filenumber) const { assert(packetdata != 0); assert(filenumberfileid()[filenumber]; return ((const MAINPACKET*)packetdata)->fileid[filenumber]; } inline const MD5Hash& MainPacket::SetId(void) const { return ((const MAINPACKET*)packetdata)->header.setid; } #endif // __MAINPACKET_H__ par2cmdline-0.4/md5.cpp0000644000000000000000000002353207664453157010423 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Convert hash values to hex ostream& operator<<(ostream &result, const MD5Hash &h) { char buffer[33]; sprintf(buffer, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", h.hash[15], h.hash[14], h.hash[13], h.hash[12], h.hash[11], h.hash[10], h.hash[9], h.hash[8], h.hash[7], h.hash[6], h.hash[5], h.hash[4], h.hash[3], h.hash[2], h.hash[1], h.hash[0]); return result << buffer; } string MD5Hash::print(void) const { char buffer[33]; sprintf(buffer, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", hash[15], hash[14], hash[13], hash[12], hash[11], hash[10], hash[9], hash[8], hash[7], hash[6], hash[5], hash[4], hash[3], hash[2], hash[1], hash[0]); return buffer; } MD5State::MD5State(void) { Reset(); } // Initialise the 16 byte state void MD5State::Reset(void) { state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; } // Update the state using 64 bytes of new data void MD5State::UpdateState(const u32 (&block)[16]) { // Primitive operations #define F1(x,y,z) ( ((x) & (y)) | ((~(x)) & (z)) ) #define F2(x,y,z) ( ((x) & (z)) | ((~(z)) & (y)) ) #define F3(x,y,z) ( (x) ^ (y) ^ (z) ) #define F4(x,y,z) ( (y) ^ ( (x) | ~(z) ) ) // The first version of ROL does not work on an Alpha CPU! //#define ROL(x,y) ( ((x) << (y)) | (((unsigned int)x) >> (32-y)) ) #define ROL(x,y) ( ((x) << (y)) | (((x) >> (32-y)) & ((1< 0) { size_t size = min(buffersize-used, length); Update(wordblock, size); length -= size; } // Update as many whole buffers as possible while (length >= buffersize) { Update(wordblock, buffersize); length -= buffersize; } // Update any remainder if (length > 0) { Update(wordblock, length); } } // Update using data from a buffer void MD5Context::Update(const void *buffer, size_t length) { const unsigned char *current = (const unsigned char *)buffer; // Update the total amount of data processed. bytes += length; // Process any whole blocks while (used + length >= buffersize) { size_t have = buffersize - used; memcpy(&block[used], current, have); current += have; length -= have; u32 wordblock[16]; for (int i=0; i<16; i++) { // Convert source data from little endian format to internal format if different wordblock[i] = ( ((u32)block[i*4+3]) << 24 ) | ( ((u32)block[i*4+2]) << 16 ) | ( ((u32)block[i*4+1]) << 8 ) | ( ((u32)block[i*4+0]) << 0 ); } MD5State::UpdateState(wordblock); used = 0; } // Store any remainder if (length > 0) { memcpy(&block[used], current, length); used += length; } } // Finalise the computation and extract the Hash value void MD5Context::Final(MD5Hash &output) { // Temporary work buffer u8 buffer[64]; // How many bits were processed u64 bits = bytes << 3; // Pad as much as needed so that there are exactly 8 bytes needed to fill the buffer size_t padding; if (used >= buffersize-8) { padding = buffersize-8 + buffersize - used; } else { padding = buffersize-8 - used; } memset(buffer, 0, padding); buffer[0] = 0x80; Update(buffer, padding); // Pad with an additional 8 bytes containing the bit count in little endian format buffer[7] = (unsigned char)((bits >> 56) & 0xFF); buffer[6] = (unsigned char)((bits >> 48) & 0xFF); buffer[5] = (unsigned char)((bits >> 40) & 0xFF); buffer[4] = (unsigned char)((bits >> 32) & 0xFF); buffer[3] = (unsigned char)((bits >> 24) & 0xFF); buffer[2] = (unsigned char)((bits >> 16) & 0xFF); buffer[1] = (unsigned char)((bits >> 8) & 0xFF); buffer[0] = (unsigned char)((bits >> 0) & 0xFF); Update(buffer, 8); for (int i = 0; i < 4; i++) { // Read out the state and convert it from internal format to little endian format output.hash[4*i+3] = (u8)((MD5State::state[i] >> 24) & 0xFF); output.hash[4*i+2] = (u8)((MD5State::state[i] >> 16) & 0xFF); output.hash[4*i+1] = (u8)((MD5State::state[i] >> 8) & 0xFF); output.hash[4*i+0] = (u8)((MD5State::state[i] >> 0) & 0xFF); } } // Return the Hash value MD5Hash MD5Context::Hash(void) const { MD5Hash output; for (unsigned int i = 0; i < 4; i++) { // Read out the state and convert it from internal format to little endian format output.hash[4*i+3] = (unsigned char)((MD5State::state[i] >> 24) & 0xFF); output.hash[4*i+2] = (unsigned char)((MD5State::state[i] >> 16) & 0xFF); output.hash[4*i+1] = (unsigned char)((MD5State::state[i] >> 8) & 0xFF); output.hash[4*i+0] = (unsigned char)((MD5State::state[i] >> 0) & 0xFF); } return output; } ostream& operator<<(ostream &result, const MD5Context &c) { char buffer[50]; sprintf(buffer, "%08X%08X%08X%08X:%08X%08X", c.state[3],c.state[2],c.state[1],c.state[0], (u32)((c.bytes >> 32) & 0xffffffff), (u32)(c.bytes & 0xffffffff)); return result << buffer; } string MD5Context::print(void) const { char buffer[50]; sprintf(buffer, "%08X%08X%08X%08X:%08X%08X", state[3],state[2],state[1],state[0], (u32)((bytes >> 32) & 0xffffffff), (u32)(bytes & 0xffffffff)); return buffer; } par2cmdline-0.4/md5.h0000644000000000000000000000734107712575220010056 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __MD5_H__ #define __MD5_H__ // This file defines the MD5Hash and MD5Context objects which are used // to compute and manipulate the MD5 Hash values for a block of data. // Usage: // // MD5Context context; // context.Update(buffer, length); // // MD5Hash hash; // context.Final(hash); // MD5 Hash value class MD5Hash { public: // Constructor does not initialise the value MD5Hash(void) {}; // Comparison operators bool operator==(const MD5Hash &other) const; bool operator!=(const MD5Hash &other) const; bool operator<(const MD5Hash &other) const; bool operator>=(const MD5Hash &other) const; bool operator>(const MD5Hash &other) const; bool operator<=(const MD5Hash &other) const; // Convert value to hex friend ostream& operator<<(ostream &s, const MD5Hash &hash); string print(void) const; // Copy and assignment MD5Hash(const MD5Hash &other); MD5Hash& operator=(const MD5Hash &other); public: u8 hash[16]; // 16 byte MD5 Hash value }; // Intermediate computation state class MD5State { public: MD5State(void); void Reset(void); public: void UpdateState(const u32 (&block)[16]); protected: u32 state[4]; // 16 byte MD5 computation state }; // MD5 computation context with 64 byte buffer class MD5Context : public MD5State { public: MD5Context(void); ~MD5Context(void) {}; void Reset(void); // Process data from a buffer void Update(const void *buffer, size_t length); // Process 0 bytes void Update(size_t length); // Compute the final hash value void Final(MD5Hash &output); // Get the Hash value and the total number of bytes processed. MD5Hash Hash(void) const; u64 Bytes(void) const {return bytes;} friend ostream& operator<<(ostream &s, const MD5Context &context); string print(void) const; protected: enum {buffersize = 64}; unsigned char block[buffersize]; size_t used; u64 bytes; }; // Compare hash values inline bool MD5Hash::operator==(const MD5Hash &other) const { return (0==memcmp(&hash, &other.hash, sizeof(hash))); } inline bool MD5Hash::operator!=(const MD5Hash &other) const { return !operator==(other); } inline bool MD5Hash::operator<(const MD5Hash &other) const { size_t index = 15; while (index > 0 && hash[index] == other.hash[index]) { index--; } return hash[index] < other.hash[index]; } inline bool MD5Hash::operator>=(const MD5Hash &other) const { return !operator<(other); } inline bool MD5Hash::operator>(const MD5Hash &other) const { return other.operator<(*this); } inline bool MD5Hash::operator<=(const MD5Hash &other) const { return !other.operator<(*this); } inline MD5Hash::MD5Hash(const MD5Hash &other) { memcpy(&hash, &other.hash, sizeof(hash)); } inline MD5Hash& MD5Hash::operator=(const MD5Hash &other) { memcpy(&hash, &other.hash, sizeof(hash)); return *this; } #endif // __MD5_H__ par2cmdline-0.4/par1fileformat.cpp0000644000000000000000000000203007664453160012632 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" PAR1MAGIC par1_magic = {{'P', 'A', 'R', '\0', '\0', '\0', '\0', '\0'}}; par2cmdline-0.4/par1fileformat.h0000644000000000000000000000423507712575335012313 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR1FILEFORMAT_H__ #define __PAR1FILEFORMAT_H__ #ifdef WIN32 #pragma pack(push, 1) #define PACKED #else #define PACKED __attribute__ ((packed)) #endif #ifdef _MSC_VER #pragma warning(disable:4200) #endif struct PAR1MAGIC {u8 magic[8];}PACKED; struct PAR1FILEHEADER { PAR1MAGIC magic; leu32 fileversion; leu32 programversion; MD5Hash controlhash; MD5Hash sethash; leu64 volumenumber; leu64 numberoffiles; leu64 filelistoffset; leu64 filelistsize; leu64 dataoffset; leu64 datasize; }PACKED; struct PAR1FILEENTRY { leu64 entrysize; leu64 status; leu64 filesize; MD5Hash hashfull; MD5Hash hash16k; leu16 name[]; }PACKED; enum FILEENTRYSTATUS { INPARITYVOLUME = 1, CHECKED = 2, }; #ifdef _MSC_VER #pragma warning(default:4200) #endif #ifdef WIN32 #pragma pack(pop) #endif #undef PACKED // Operators for comparing the MAGIC values inline bool operator == (const PAR1MAGIC &left, const PAR1MAGIC &right) { return (0==memcmp(&left, &right, sizeof(left))); } inline bool operator != (const PAR1MAGIC &left, const PAR1MAGIC &right) { return !operator==(left, right); } extern PAR1MAGIC par1_magic; #endif //__PAR1FILEFORMAT_H__ par2cmdline-0.4/par1repairer.cpp0000755000000000000000000011334210037510340012305 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif static u32 smartpar11 = 0x03000101; Par1Repairer::Par1Repairer(void) { filelist = 0; filelistsize = 0; blocksize = 0; completefilecount = 0; renamedfilecount = 0; damagedfilecount = 0; missingfilecount = 0; inputbuffer = 0; outputbuffer = 0; noiselevel = CommandLine::nlNormal; } Par1Repairer::~Par1Repairer(void) { map::iterator i = recoveryblocks.begin(); while (i != recoveryblocks.end()) { DataBlock *datablock = i->second; delete datablock; ++i; } vector::iterator sourceiterator = sourcefiles.begin(); while (sourceiterator != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sourceiterator; delete sourcefile; ++sourceiterator; } sourceiterator = extrafiles.begin(); while (sourceiterator != extrafiles.end()) { Par1RepairerSourceFile *sourcefile = *sourceiterator; delete sourcefile; ++sourceiterator; } delete [] filelist; } Result Par1Repairer::Process(const CommandLine &commandline, bool dorepair) { // How noisy should we be noiselevel = commandline.GetNoiseLevel(); // Get filesnames from the command line string par1filename = commandline.GetParFilename(); const list &extrafiles = commandline.GetExtraFiles(); // Determine the searchpath from the location of the main PAR file string name; DiskFile::SplitFilename(par1filename, searchpath, name); // Load the main PAR file if (!LoadRecoveryFile(searchpath + name)) return eLogicError; // Load other PAR files related to the main PAR file if (!LoadOtherRecoveryFiles(par1filename)) return eLogicError; // Load any extra PAR files specified on the command line if (!LoadExtraRecoveryFiles(extrafiles)) return eLogicError; if (noiselevel > CommandLine::nlQuiet) cout << endl << "Verifying source files:" << endl << endl; // Check for the existence of and verify each of the source files if (!VerifySourceFiles()) return eFileIOError; if (completefilecount CommandLine::nlQuiet) cout << endl << "Scanning extra files:" << endl << endl; // Check any other files specified on the command line to see if they are // actually copies of the source files that have the wrong filename if (!VerifyExtraFiles(extrafiles)) return eLogicError; } // Find out how much data we have found UpdateVerificationResults(); if (noiselevel > CommandLine::nlSilent) cout << endl; // Check the verification results and report the details if (!CheckVerificationResults()) return eRepairNotPossible; // Are any of the files incomplete if (completefilecount CommandLine::nlSilent) cout << endl; // Rename any damaged or missnamed target files. if (!RenameTargetFiles()) return eFileIOError; // Are we still missing any files if (completefilecount CommandLine::nlSilent) cout << endl; // Set the total amount of data to be processed. progress = 0; totaldata = blocksize * sourcefiles.size() * verifylist.size(); // Start at an offset of 0 within a block. u64 blockoffset = 0; while (blockoffset < blocksize) // Continue until the end of the block. { // Work out how much data to process this time. size_t blocklength = (size_t)min((u64)chunksize, blocksize-blockoffset); // Read source data, process it through the RS matrix and write it to disk. if (!ProcessData(blockoffset, blocklength)) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } // Advance to the need offset within each block blockoffset += blocklength; } if (noiselevel > CommandLine::nlSilent) cout << endl << "Verifying repaired files:" << endl << endl; // Verify that all of the reconstructed target files are now correct if (!VerifyTargetFiles()) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } } // Are all of the target files now complete? if (completefilecount CommandLine::nlSilent) cout << endl << "Repair complete." << endl; } } else { return eRepairPossible; } } return eSuccess; } bool Par1Repairer::LoadRecoveryFile(string filename) { // Skip the file if it has already been processed if (diskfilemap.Find(filename) != 0) { return true; } DiskFile *diskfile = new DiskFile; // Open the file if (!diskfile->Open(filename)) { // If we could not open the file, ignore the error and // proceed to the next file delete diskfile; return true; } if (noiselevel > CommandLine::nlSilent) { string path; string name; DiskFile::SplitFilename(filename, path, name); cout << "Loading \"" << name << "\"." << endl; } bool havevolume = false; u32 volumenumber = 0; // How big is the file u64 filesize = diskfile->FileSize(); if (filesize >= sizeof(PAR1FILEHEADER)) { // Allocate a buffer to read data into size_t buffersize = (size_t)min((u64)1048576, filesize); u8 *buffer = new u8[buffersize]; do { PAR1FILEHEADER fileheader; if (!diskfile->Read(0, &fileheader, sizeof(fileheader))) break; // Is this really a PAR file? if (fileheader.magic != par1_magic) break; // Is the version number correct? if (fileheader.fileversion != 0x00010000) break; ignore16kfilehash = (fileheader.programversion == smartpar11); // Prepare to carry out MD5 Hash check of the Control Hash MD5Context context; u64 offset = offsetof(PAR1FILEHEADER, sethash); // Process until the end of the file is reached while (offset < filesize) { // How much data should we read? size_t want = (size_t)min((u64)buffersize, filesize-offset); if (!diskfile->Read(offset, buffer, want)) break; context.Update(buffer, want); offset += want; } // Did we read the whole file if (offset < filesize) break; // Compute the hash value MD5Hash hash; context.Final(hash); // Is it correct? if (hash != fileheader.controlhash) break; // Check that the volume number is ok if (fileheader.volumenumber >= 256) break; // Are there any files? if (fileheader.numberoffiles == 0 || fileheader.filelistoffset < sizeof(PAR1FILEHEADER) || fileheader.filelistsize == 0) break; // Verify that the file list and data offsets are ok if ((fileheader.filelistoffset + fileheader.filelistsize > filesize) || (fileheader.datasize && (fileheader.dataoffset < sizeof(fileheader) || fileheader.dataoffset + fileheader.datasize > filesize)) || (fileheader.datasize && (fileheader.filelistoffset <= fileheader.dataoffset && fileheader.dataoffset < fileheader.filelistoffset+fileheader.filelistsize || fileheader.dataoffset <= fileheader.filelistoffset && fileheader.filelistoffset < fileheader.dataoffset + fileheader.datasize))) break; // Check the size of the file list if (fileheader.filelistsize > 200000) break; // If we already have a copy of the file list, make sure this one has the same size if (filelist != 0 && filelistsize != fileheader.filelistsize) break; // Allocate a buffer to hold a copy of the file list unsigned char *temp = new unsigned char[(size_t)fileheader.filelistsize]; // Read the file list into the buffer if (!diskfile->Read(fileheader.filelistoffset, temp, (size_t)fileheader.filelistsize)) { delete [] temp; break; } // If we already have a copy of the file list, make sure this copy is identical if (filelist != 0) { bool match = (0 == memcmp(filelist, temp, filelistsize)); delete [] temp; if (!match) break; } else { // Prepare to scan the file list unsigned char *current = temp; size_t remaining = (size_t)fileheader.filelistsize; unsigned int fileindex = 0; // Allocate a buffer to copy each file entry into so that // all fields will be correctly aligned in memory. PAR1FILEENTRY *fileentry = (PAR1FILEENTRY*)new u64[(remaining + sizeof(u64)-1)/sizeof(u64)]; // Process until we run out of files or data while (remaining > 0 && fileindex < fileheader.numberoffiles) { // Copy fixed portion of file entry memcpy((void*)fileentry, (void*)current, sizeof(PAR1FILEENTRY)); // Is there enough data remaining if (remaining < sizeof(fileentry->entrysize) || remaining < fileentry->entrysize) break; // Check the length of the filename if (fileentry->entrysize <= sizeof(PAR1FILEENTRY)) break; // Check the file size if (blocksize < fileentry->filesize) blocksize = fileentry->filesize; // Copy whole of file entry memcpy((void*)fileentry, (void*)current, (size_t)(u64)fileentry->entrysize); // Create source file and add it to the appropriate list Par1RepairerSourceFile *sourcefile = new Par1RepairerSourceFile(fileentry, searchpath); if (fileentry->status & INPARITYVOLUME) { sourcefiles.push_back(sourcefile); } else { extrafiles.push_back(sourcefile); } remaining -= (size_t)fileentry->entrysize; current += (size_t)fileentry->entrysize; fileindex++; } delete [] (u64*)fileentry; // Did we find the correct number of files if (fileindex < fileheader.numberoffiles) { vector::iterator i = sourcefiles.begin(); while (i != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *i; delete sourcefile; ++i; } sourcefiles.clear(); i = extrafiles.begin(); while (i != extrafiles.end()) { Par1RepairerSourceFile *sourcefile = *i; delete sourcefile; ++i; } extrafiles.clear(); delete [] temp; break; } filelist = temp; filelistsize = (u32)fileheader.filelistsize; } // Is this a recovery volume? if (fileheader.volumenumber > 0) { // Make sure there is data and that it is the correct size if (fileheader.dataoffset == 0 || fileheader.datasize != blocksize) break; // What volume number is this? volumenumber = (u32)(fileheader.volumenumber - 1); // Do we already have this volume? if (recoveryblocks.find(volumenumber) == recoveryblocks.end()) { // Create a data block DataBlock *datablock = new DataBlock; datablock->SetLength(blocksize); datablock->SetLocation(diskfile, fileheader.dataoffset); // Store it in the map recoveryblocks.insert(pair(volumenumber, datablock)); havevolume = true; } } } while (false); delete [] buffer; } // We have finished with the file for now diskfile->Close(); if (noiselevel > CommandLine::nlQuiet) { if (havevolume) { cout << "Loaded recovery volume " << volumenumber << endl; } else { cout << "No new recovery volumes found" << endl; } } // Remember that the file was processed bool success = diskfilemap.Insert(diskfile); assert(success); return true; } bool Par1Repairer::LoadOtherRecoveryFiles(string filename) { // Split the original PAR filename into path and name parts string path; string name; DiskFile::SplitFilename(filename, path, name); // Find the file extension string::size_type where = name.find_last_of('.'); if (where != string::npos) { // remove it name = name.substr(0, where); } // Search for additional PAR files string wildcard = name + ".???"; list *files = DiskFile::FindFiles(path, wildcard); for (list::const_iterator s=files->begin(); s!=files->end(); ++s) { string filename = *s; // Find the file extension where = filename.find_last_of('.'); if (where != string::npos) { string tail = filename.substr(where+1); // Check the the file extension is the correct form if ((tail[0] == 'P' || tail[0] == 'p') && ( (tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r') || isdigit(tail[1]) && isdigit(tail[2]) )) { LoadRecoveryFile(filename); } } } delete files; return true; } // Load packets from any other PAR files whose names are given on the command line bool Par1Repairer::LoadExtraRecoveryFiles(const list &extrafiles) { for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { string filename = i->FileName(); // Find the file extension string::size_type where = filename.find_last_of('.'); if (where != string::npos) { string tail = filename.substr(where+1); // Check the the file extension is the correct form if ((tail[0] == 'P' || tail[0] == 'p') && ( (tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r') || isdigit(tail[1]) && isdigit(tail[2]) )) { LoadRecoveryFile(filename); } } } return true; } // Attempt to verify all of the source files bool Par1Repairer::VerifySourceFiles(void) { bool finalresult = true; u32 filenumber = 0; vector::iterator sourceiterator = sourcefiles.begin(); while (sourceiterator != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sourceiterator; string filename = sourcefile->FileName(); // Check to see if we have already used this file if (diskfilemap.Find(filename) != 0) { // The file has already been used! cerr << "Source file " << filenumber+1 << " is a duplicate." << endl; return false; } DiskFile *diskfile = new DiskFile; // Does the target file exist if (diskfile->Open(filename)) { // Yes. Record that fact. sourcefile->SetTargetExists(true); // Remember that the DiskFile is the target file sourcefile->SetTargetFile(diskfile); // Remember that we have processed this file bool success = diskfilemap.Insert(diskfile); assert(success); // Do the actual verification if (!VerifyDataFile(diskfile, sourcefile)) finalresult = false; // We have finished with the file for now diskfile->Close(); // Find out how much data we have found UpdateVerificationResults(); } else { // The file does not exist. delete diskfile; if (noiselevel > CommandLine::nlSilent) { string path; string name; DiskFile::SplitFilename(filename, path, name); cout << "Target: \"" << name << "\" - missing." << endl; } } ++sourceiterator; ++filenumber; } return finalresult; } // Scan any extra files specified on the command line bool Par1Repairer::VerifyExtraFiles(const list &extrafiles) { for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end() && completefilecountFileName(); bool skip = false; // Find the file extension string::size_type where = filename.find_last_of('.'); if (where != string::npos) { string tail = filename.substr(where+1); // Check the the file extension is the correct form if ((tail[0] == 'P' || tail[0] == 'p') && ( (tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r') || isdigit(tail[1]) && isdigit(tail[2]) )) { skip = true; } } if (!skip) { filename = DiskFile::GetCanonicalPathname(filename); // Has this file already been dealt with if (diskfilemap.Find(filename) == 0) { DiskFile *diskfile = new DiskFile; // Does the file exist if (!diskfile->Open(filename)) { delete diskfile; continue; } // Remember that we have processed this file bool success = diskfilemap.Insert(diskfile); assert(success); // Do the actual verification VerifyDataFile(diskfile, 0); // Ignore errors // We have finished with the file for now diskfile->Close(); // Find out how much data we have found UpdateVerificationResults(); } } } return true; } bool Par1Repairer::VerifyDataFile(DiskFile *diskfile, Par1RepairerSourceFile *sourcefile) { Par1RepairerSourceFile *match = 0; string path; string name; DiskFile::SplitFilename(diskfile->FileName(), path, name); // How big is the file we are checking u64 filesize = diskfile->FileSize(); if (filesize == 0) return true; // Search for the first file that is the correct size vector::iterator sourceiterator = sourcefiles.begin(); while (sourceiterator != sourcefiles.end() && filesize != (*sourceiterator)->FileSize()) { ++sourceiterator; } // Are there any files that are the correct size? if (sourceiterator != sourcefiles.end()) { // Allocate a buffer to compute the file hash size_t buffersize = (size_t)min((u64)1048576, filesize); char *buffer = new char[buffersize]; // Read the first 16k of the file size_t want = (size_t)min((u64)16384, filesize); if (!diskfile->Read(0, buffer, want)) { delete [] buffer; return false; } // Compute the MD5 hash of the first 16k MD5Context contextfull; contextfull.Update(buffer, want); MD5Context context16k = contextfull; MD5Hash hash16k; context16k.Final(hash16k); if (!ignore16kfilehash) { // Search for the first file that has the correct 16k hash while (sourceiterator != sourcefiles.end() && (filesize != (*sourceiterator)->FileSize() || hash16k != (*sourceiterator)->Hash16k())) { ++sourceiterator; } } // Are there any files with the correct 16k hash? if (sourceiterator != sourcefiles.end()) { // Compute the MD5 hash of the whole file if (filesize > 16384) { u64 progress = 0; u64 offset = 16384; while (offset < filesize) { if (noiselevel > CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * (progress) / filesize); u32 newfraction = (u32)(1000 * (progress=offset) / filesize); if (oldfraction != newfraction) { cout << "Scanning: \"" << name << "\": " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } want = (size_t)min((u64)buffersize, filesize-offset); if (!diskfile->Read(offset, buffer, want)) { delete [] buffer; return false; } contextfull.Update(buffer, want); offset += want; } } MD5Hash hashfull; contextfull.Final(hashfull); // Search for the first file that has the correct full hash while (sourceiterator != sourcefiles.end() && (filesize != (*sourceiterator)->FileSize() || (!ignore16kfilehash && hash16k != (*sourceiterator)->Hash16k()) || hashfull != (*sourceiterator)->HashFull())) { ++sourceiterator; } // Are there any files with the correct full hash? if (sourceiterator != sourcefiles.end()) { // If a source file was originally specified, check to see if it is a match if (sourcefile != 0 && sourcefile->FileSize() == filesize && (ignore16kfilehash || sourcefile->Hash16k() == hash16k) && sourcefile->HashFull() == hashfull) { match = sourcefile; } else { // Search for a file which matches and has not already been matched while (sourceiterator != sourcefiles.end() && (filesize != (*sourceiterator)->FileSize() || (!ignore16kfilehash && hash16k != (*sourceiterator)->Hash16k()) || hashfull != (*sourceiterator)->HashFull() || (*sourceiterator)->GetCompleteFile() != 0)) { ++sourceiterator; } // Did we find a match if (sourceiterator != sourcefiles.end()) { match = *sourceiterator; } } } } delete [] buffer; } // Did we find a match if (match != 0) { match->SetCompleteFile(diskfile); if (noiselevel > CommandLine::nlSilent) { // Was the match the file we were originally looking for if (match == sourcefile) { cout << "Target: \"" << name << "\" - found." << endl; } // Were we looking for a specific file else if (sourcefile != 0) { string targetname; DiskFile::SplitFilename(sourcefile->FileName(), path, targetname); cout << "Target: \"" << name << "\" - is a match for \"" << targetname << "\"." << endl; } } else { if (noiselevel > CommandLine::nlSilent) { string targetname; DiskFile::SplitFilename(match->FileName(), path, targetname); cout << "File: \"" << name << "\" - is a match for \"" << targetname << "\"." << endl; } } } else { if (noiselevel > CommandLine:: nlSilent) cout << "File: \"" << name << "\" - no data found." << endl; } return true; } void Par1Repairer::UpdateVerificationResults(void) { completefilecount = 0; renamedfilecount = 0; damagedfilecount = 0; missingfilecount = 0; vector::iterator sf = sourcefiles.begin(); // Check the recoverable files while (sf != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sf; // Was a perfect match for the file found if (sourcefile->GetCompleteFile() != 0) { // Is it the target file or a different one if (sourcefile->GetCompleteFile() == sourcefile->GetTargetFile()) { completefilecount++; } else { renamedfilecount++; } } else { // Does the target file exist if (sourcefile->GetTargetExists()) { damagedfilecount++; } else { missingfilecount++; } } ++sf; } } bool Par1Repairer::CheckVerificationResults(void) { // Is repair needed if (completefilecount < sourcefiles.size() || renamedfilecount > 0 || damagedfilecount > 0 || missingfilecount > 0) { if (noiselevel > CommandLine::nlSilent) cout << "Repair is required." << endl; if (noiselevel > CommandLine::nlQuiet) { if (renamedfilecount > 0) cout << renamedfilecount << " file(s) have the wrong name." << endl; if (missingfilecount > 0) cout << missingfilecount << " file(s) are missing." << endl; if (damagedfilecount > 0) cout << damagedfilecount << " file(s) exist but are damaged." << endl; if (completefilecount > 0) cout << completefilecount << " file(s) are ok." << endl; } // Is repair possible if (recoveryblocks.size() >= damagedfilecount+missingfilecount) { if (noiselevel > CommandLine::nlSilent) cout << "Repair is possible." << endl; if (noiselevel > CommandLine::nlQuiet) { if (recoveryblocks.size() > damagedfilecount+missingfilecount) cout << "You have an excess of " << (u32)recoveryblocks.size() - (damagedfilecount+missingfilecount) << " recovery files." << endl; if (damagedfilecount+missingfilecount > 0) cout << damagedfilecount+missingfilecount << " recovery files will be used to repair." << endl; else if (recoveryblocks.size()) cout << "None of the recovery files will be used for the repair." << endl; } return true; } else { if (noiselevel > CommandLine::nlSilent) { cout << "Repair is not possible." << endl; cout << "You need " << damagedfilecount+missingfilecount - recoveryblocks.size() << " more recovery files to be able to repair." << endl; } return false; } } else { if (noiselevel > CommandLine::nlSilent) cout << "All files are correct, repair is not required." << endl; return true; } return true; } bool Par1Repairer::RenameTargetFiles(void) { vector::iterator sf = sourcefiles.begin(); // Rename any damaged target files while (sf != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sf; // If the target file exists but is not a complete version of the file if (sourcefile->GetTargetExists() && sourcefile->GetTargetFile() != sourcefile->GetCompleteFile()) { DiskFile *targetfile = sourcefile->GetTargetFile(); // Rename it diskfilemap.Remove(targetfile); if (!targetfile->Rename()) return false; bool success = diskfilemap.Insert(targetfile); assert(success); // We no longer have a target file sourcefile->SetTargetExists(false); sourcefile->SetTargetFile(0); } ++sf; } sf = sourcefiles.begin(); // Rename any missnamed but complete versions of the files while (sf != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sf; // If there is no targetfile and there is a complete version if (sourcefile->GetTargetFile() == 0 && sourcefile->GetCompleteFile() != 0) { DiskFile *targetfile = sourcefile->GetCompleteFile(); // Rename it diskfilemap.Remove(targetfile); if (!targetfile->Rename(sourcefile->FileName())) return false; bool success = diskfilemap.Insert(targetfile); assert(success); // This file is now the target file sourcefile->SetTargetExists(true); sourcefile->SetTargetFile(targetfile); // We have one more complete file completefilecount++; } ++sf; } return true; } // Work out which files are being repaired, create them, and allocate // target DataBlocks to them, and remember them for later verification. bool Par1Repairer::CreateTargetFiles(void) { vector::iterator sf = sourcefiles.begin(); // Create any missing target files while (sf != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sf; // If the file does not exist if (!sourcefile->GetTargetExists()) { DiskFile *targetfile = new DiskFile; string filename = sourcefile->FileName(); u64 filesize = sourcefile->FileSize(); // Create the target file if (!targetfile->Create(filename, filesize)) { delete targetfile; return false; } // This file is now the target file sourcefile->SetTargetExists(true); sourcefile->SetTargetFile(targetfile); // Remember this file bool success = diskfilemap.Insert(targetfile); assert(success); sourcefile->SetTargetBlock(targetfile); // Add the file to the list of those that will need to be verified // once the repair has completed. verifylist.push_back(sourcefile); } ++sf; } return true; } // Work out which data blocks are available, which need to be recreated, // and compute the appropriate Reed Solomon matrix. bool Par1Repairer::ComputeRSmatrix(void) { inputblocks.resize(sourcefiles.size()); // The DataBlocks that will read from disk outputblocks.resize(verifylist.size()); // Those DataBlocks that will re recalculated vector::iterator inputblock = inputblocks.begin(); vector::iterator outputblock = outputblocks.begin(); // Build an array listing which source data blocks are present and which are missing vector present; present.resize(sourcefiles.size()); vector::iterator sourceiterator = sourcefiles.begin(); vector::iterator pres = present.begin(); // Iterate through all source files while (sourceiterator != sourcefiles.end()) { Par1RepairerSourceFile *sourcefile = *sourceiterator; DataBlock *sourceblock = sourcefile->SourceBlock(); DataBlock *targetblock = sourcefile->TargetBlock(); // Was this block found if (sourceblock->IsSet()) { // Open the file the block was found in. if (!sourceblock->Open()) { return false; } // Record that the block was found *pres = true; // Add the block to the list of those which will be read // as input (and which might also need to be copied). *inputblock = sourceblock; ++inputblock; } else { // Record that the block was missing *pres = false; // Add the block to the list of those to be written *outputblock = targetblock; ++outputblock; } ++sourceiterator; ++pres; } // Set the number of source blocks and which of them are present if (!rs.SetInput(present)) { return false; } // Start iterating through the available recovery packets map::iterator recoveryiterator = recoveryblocks.begin(); // Continue to fill the remaining list of data blocks to be read while (inputblock != inputblocks.end()) { // Get the next available recovery block u32 exponent = recoveryiterator->first; DataBlock *recoveryblock = recoveryiterator->second; // Make sure the file is open if (!recoveryblock->Open()) { return false; } // Add the recovery block to the list of blocks that will be read *inputblock = recoveryblock; // Record that the corresponding exponent value is the next one // to use in the RS matrix if (!rs.SetOutput(true, (u16)exponent)) { return false; } ++inputblock; ++recoveryiterator; } // If we need to, compute and solve the RS matrix if (verifylist.size() == 0) { return true; } bool success = rs.Compute(noiselevel); return success; } // Allocate memory buffers for reading and writing data to disk. bool Par1Repairer::AllocateBuffers(size_t memorylimit) { // Would single pass processing use too much memory if (blocksize * verifylist.size() > memorylimit) { // Pick a size that is small enough chunksize = ~3 & (memorylimit / verifylist.size()); } else { chunksize = (size_t)blocksize; } // Allocate the two buffers inputbuffersize = (size_t)chunksize; inputbuffer = new u8[inputbuffersize]; outputbufferalignment = (inputbuffersize + sizeof(u32)-1) & ~(sizeof(u32)-1); outputbuffersize = outputbufferalignment * verifylist.size(); outputbuffer = new u8[outputbuffersize]; if (inputbuffer == NULL || outputbuffer == NULL) { cerr << "Could not allocate buffer memory." << endl; return false; } return true; } // Read source data, process it through the RS matrix and write it to disk. bool Par1Repairer::ProcessData(u64 blockoffset, size_t blocklength) { u64 totalwritten = 0; // Clear the output buffer memset(outputbuffer, 0, outputbuffersize); vector::iterator inputblock = inputblocks.begin(); u32 inputindex = 0; // Are there any blocks which need to be reconstructed if (verifylist.size() > 0) { // For each input block while (inputblock != inputblocks.end()) { // Read data from the current input block if (!(*inputblock)->ReadData(blockoffset, blocklength, inputbuffer)) return false; // For each output block for (u32 outputindex=0; outputindex CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * progress / totaldata); progress += blocklength; u32 newfraction = (u32)(1000 * progress / totaldata); if (oldfraction != newfraction) { cout << "Repairing: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } } ++inputblock; ++inputindex; } } if (noiselevel > CommandLine::nlQuiet) cout << "Writing recovered data\r"; // For each output block that has been recomputed vector::iterator outputblock = outputblocks.begin(); for (u32 outputindex=0; outputindexWriteData(blockoffset, blocklength, outbuf, wrote)) return false; totalwritten += wrote; ++outputblock; } if (noiselevel > CommandLine::nlQuiet) cout << "Wrote " << totalwritten << " bytes to disk" << endl; return true; } // Verify that all of the reconstructed target files are now correct bool Par1Repairer::VerifyTargetFiles(void) { bool finalresult = true; // Verify the target files in alphabetical order // sort(verifylist.begin(), verifylist.end(), SortSourceFilesByFileName); // Iterate through each file in the verification list for (list::iterator sf = verifylist.begin(); sf != verifylist.end(); ++sf) { Par1RepairerSourceFile *sourcefile = *sf; DiskFile *targetfile = sourcefile->GetTargetFile(); // Close the file if (targetfile->IsOpen()) targetfile->Close(); // Say we don't have a complete version of the file sourcefile->SetCompleteFile(0); // Re-open the target file if (!targetfile->Open()) { finalresult = false; continue; } // Verify the file again if (!VerifyDataFile(targetfile, sourcefile)) finalresult = false; // Close the file again targetfile->Close(); // Find out how much data we have found UpdateVerificationResults(); } return finalresult; } // Delete all of the partly reconstructed files bool Par1Repairer::DeleteIncompleteTargetFiles(void) { list::iterator sf = verifylist.begin(); // Iterate through each file in the verification list while (sf != verifylist.end()) { Par1RepairerSourceFile *sourcefile = *sf; if (sourcefile->GetTargetExists()) { DiskFile *targetfile = sourcefile->GetTargetFile(); // Close and delete the file if (targetfile->IsOpen()) targetfile->Close(); targetfile->Delete(); // Forget the file diskfilemap.Remove(targetfile); delete targetfile; // There is no target file sourcefile->SetTargetExists(false); sourcefile->SetTargetFile(0); } ++sf; } return true; } par2cmdline-0.4/par1repairer.h0000644000000000000000000001143310037475315011761 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR1REPAIRER_H__ #define __PAR1REPAIRER_H__ class Par1Repairer { public: Par1Repairer(void); ~Par1Repairer(void); Result Process(const CommandLine &commandline, bool dorepair); protected: // Load the main PAR file bool LoadRecoveryFile(string filename); // Load other PAR files related to the main PAR file bool LoadOtherRecoveryFiles(string filename); // Load any extra PAR files specified on the command line bool LoadExtraRecoveryFiles(const list &extrafiles); // Check for the existence of and verify each of the source files bool VerifySourceFiles(void); // Check any other files specified on the command line to see if they are // actually copies of the source files that have the wrong filename bool VerifyExtraFiles(const list &extrafiles); // Attempt to match the data in the DiskFile with the source file bool VerifyDataFile(DiskFile *diskfile, Par1RepairerSourceFile *sourcefile); // Determine how many files are missing, damaged etc. void UpdateVerificationResults(void); // Check the verification results and report the details bool CheckVerificationResults(void); // Rename any damaged or missnamed target files. bool RenameTargetFiles(void); // Work out which files are being repaired, create them, and allocate // target DataBlocks to them, and remember them for later verification. bool CreateTargetFiles(void); // Work out which data blocks are available, which need to be recreated, // and compute the appropriate Reed Solomon matrix. bool ComputeRSmatrix(void); // Allocate memory buffers for reading and writing data to disk. bool AllocateBuffers(size_t memorylimit); // Read source data, process it through the RS matrix and write it to disk. bool ProcessData(u64 blockoffset, size_t blocklength); // Verify that all of the reconstructed target files are now correct bool VerifyTargetFiles(void); // Delete all of the partly reconstructed files bool DeleteIncompleteTargetFiles(void); protected: CommandLine::NoiseLevel noiselevel; // How noisy we should be string searchpath; // Where to find files on disk DiskFileMap diskfilemap; // Map from filename to DiskFile map recoveryblocks; // The recovery data (mapped by exponent) unsigned char *filelist; u32 filelistsize; u64 blocksize; // The size of recovery and data blocks u64 chunksize; // How much of a block can be processed. vector sourcefiles; vector extrafiles; u32 completefilecount; u32 renamedfilecount; u32 damagedfilecount; u32 missingfilecount; list verifylist; vector inputblocks; // Which DataBlocks will be read from disk vector outputblocks; // Which DataBlocks have to calculated using RS ReedSolomon rs; // The Reed Solomon matrix. u64 progress; // How much data has been processed. u64 totaldata; // Total amount of data to be processed. size_t inputbuffersize; u8 *inputbuffer; // Buffer for reading DataBlocks (chunksize) size_t outputbufferalignment; size_t outputbuffersize; u8 *outputbuffer; // Buffer for writing DataBlocks (chunksize * missingblockcount) bool ignore16kfilehash; // The 16k file hash values may be invalid }; #endif // __PAR1REPAIRER_H__ par2cmdline-0.4/par1repairersourcefile.cpp0000644000000000000000000000600107716445056014401 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif Par1RepairerSourceFile::Par1RepairerSourceFile(PAR1FILEENTRY *fileentry, string searchpath) { targetexists = false; targetfile = 0; completefile = 0; hashfull = fileentry->hashfull; hash16k = fileentry->hash16k; filesize = fileentry->filesize; u32 namelen = (u32)((fileentry->entrysize - offsetof(PAR1FILEENTRY, name)) / 2); for (u32 index=0; indexname[index]; if (ch >= 256) { // Convert the Unicode character to two characters filename += ch && 255; filename += ch >> 8; } else { filename += ch & 255; } } // Translate any characters the OS does not like; filename = DiskFile::TranslateFilename(filename); // Strip the path from the filename string::size_type where; if (string::npos != (where = filename.find_last_of('\\')) || string::npos != (where = filename.find_last_of('/')) #ifdef WIN32 || string::npos != (where = filename.find_last_of(':')) #endif ) { filename = filename.substr(where+1); } filename = searchpath + filename; } Par1RepairerSourceFile::~Par1RepairerSourceFile(void) { } void Par1RepairerSourceFile::SetTargetFile(DiskFile *diskfile) { targetfile = diskfile; } DiskFile* Par1RepairerSourceFile::GetTargetFile(void) const { return targetfile; } void Par1RepairerSourceFile::SetTargetExists(bool exists) { targetexists = exists; } bool Par1RepairerSourceFile::GetTargetExists(void) const { return targetexists; } void Par1RepairerSourceFile::SetCompleteFile(DiskFile *diskfile) { completefile = diskfile; sourceblock.SetLocation(diskfile, 0); sourceblock.SetLength(diskfile ? diskfile->FileSize() : 0); } DiskFile* Par1RepairerSourceFile::GetCompleteFile(void) const { return completefile; } void Par1RepairerSourceFile::SetTargetBlock(DiskFile *diskfile) { targetblock.SetLocation(diskfile, 0); targetblock.SetLength(diskfile->FileSize()); } par2cmdline-0.4/par1repairersourcefile.h0000644000000000000000000000512107664453160014045 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR1REPAIRERSOURCEFILE_H__ #define __PAR1REPAIRERSOURCEFILE_H__ // The Par1RepairerSourceFile object is used during verification and repair // to record details about a particular source file and the data blocks // for that file. class Par1RepairerSourceFile { public: // Construct the object and set the description and verification packets Par1RepairerSourceFile(PAR1FILEENTRY *fileentry, string searchpath); ~Par1RepairerSourceFile(void); string FileName(void) const {return filename;} u64 FileSize(void) const {return filesize;} const MD5Hash& HashFull(void) const {return hashfull;} const MD5Hash& Hash16k(void) const {return hash16k;} // Set/Get which DiskFile will contain the final repaired version of the file void SetTargetFile(DiskFile *diskfile); DiskFile* GetTargetFile(void) const; // Set/Get whether or not the target file actually exists void SetTargetExists(bool exists); bool GetTargetExists(void) const; // Set/Get which DiskFile contains a full undamaged version of the source file void SetCompleteFile(DiskFile *diskfile); DiskFile* GetCompleteFile(void) const; void SetTargetBlock(DiskFile *diskfile); DataBlock* SourceBlock(void) {return &sourceblock;} DataBlock* TargetBlock(void) {return &targetblock;} protected: string filename; u64 filesize; MD5Hash hashfull; MD5Hash hash16k; DataBlock sourceblock; DataBlock targetblock; bool targetexists; // Whether the target file exists DiskFile *targetfile; // The final version of the file DiskFile *completefile; // A complete version of the file }; #endif // __PAR1REPAIRERSOURCEFILE_H__ par2cmdline-0.4/par2creator.cpp0000644000000000000000000007516710037511271012151 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif Par2Creator::Par2Creator(void) : noiselevel(CommandLine::nlUnknown) , blocksize(0) , chunksize(0) , inputbuffer(0) , outputbuffer(0) , sourcefilecount(0) , sourceblockcount(0) , largestfilesize(0) , recoveryfilescheme(CommandLine::scUnknown) , recoveryfilecount(0) , recoveryblockcount(0) , firstrecoveryblock(0) , mainpacket(0) , creatorpacket(0) , deferhashcomputation(false) { } Par2Creator::~Par2Creator(void) { delete mainpacket; delete creatorpacket; delete [] (u8*)inputbuffer; delete [] (u8*)outputbuffer; vector::iterator sourcefile = sourcefiles.begin(); while (sourcefile != sourcefiles.end()) { delete *sourcefile; ++sourcefile; } } Result Par2Creator::Process(const CommandLine &commandline) { // Get information from commandline noiselevel = commandline.GetNoiseLevel(); blocksize = commandline.GetBlockSize(); sourceblockcount = commandline.GetBlockCount(); const list extrafiles = commandline.GetExtraFiles(); sourcefilecount = (u32)extrafiles.size(); u32 redundancy = commandline.GetRedundancy(); recoveryblockcount = commandline.GetRecoveryBlockCount(); recoveryfilecount = commandline.GetRecoveryFileCount(); firstrecoveryblock = commandline.GetFirstRecoveryBlock(); recoveryfilescheme = commandline.GetRecoveryFileScheme(); string par2filename = commandline.GetParFilename(); size_t memorylimit = commandline.GetMemoryLimit(); largestfilesize = commandline.GetLargestSourceSize(); // Compute block size from block count or vice versa depending on which was // specified on the command line if (!ComputeBlockSizeAndBlockCount(extrafiles)) return eInvalidCommandLineArguments; // Determine how many recovery blocks to create based on the source block // count and the requested level of redundancy. if (redundancy > 0 && !ComputeRecoveryBlockCount(redundancy)) return eInvalidCommandLineArguments; // Determine how much recovery data can be computed on one pass if (!CalculateProcessBlockSize(memorylimit)) return eLogicError; // Determine how many recovery files to create. if (!ComputeRecoveryFileCount()) return eInvalidCommandLineArguments; if (noiselevel > CommandLine::nlQuiet) { // Display information. cout << "Block size: " << blocksize << endl; cout << "Source file count: " << sourcefilecount << endl; cout << "Source block count: " << sourceblockcount << endl; if (redundancy>0 || recoveryblockcount==0) cout << "Redundancy: " << redundancy << '%' << endl; cout << "Recovery block count: " << recoveryblockcount << endl; cout << "Recovery file count: " << recoveryfilecount << endl; cout << endl; } // Open all of the source files, compute the Hashes and CRC values, and store // the results in the file verification and file description packets. if (!OpenSourceFiles(extrafiles)) return eFileIOError; // Create the main packet and determine the setid to use with all packets if (!CreateMainPacket()) return eLogicError; // Create the creator packet. if (!CreateCreatorPacket()) return eLogicError; // Initialise all of the source blocks ready to start reading data from the source files. if (!CreateSourceBlocks()) return eLogicError; // Create all of the output files and allocate all packets to appropriate file offets. if (!InitialiseOutputFiles(par2filename)) return eFileIOError; if (recoveryblockcount > 0) { // Allocate memory buffers for reading and writing data to disk. if (!AllocateBuffers()) return eMemoryError; // Compute the Reed Solomon matrix if (!ComputeRSMatrix()) return eLogicError; // Set the total amount of data to be processed. progress = 0; totaldata = blocksize * sourceblockcount * recoveryblockcount; // Start at an offset of 0 within a block. u64 blockoffset = 0; while (blockoffset < blocksize) // Continue until the end of the block. { // Work out how much data to process this time. size_t blocklength = (size_t)min((u64)chunksize, blocksize-blockoffset); // Read source data, process it through the RS matrix and write it to disk. if (!ProcessData(blockoffset, blocklength)) return eFileIOError; blockoffset += blocklength; } if (noiselevel > CommandLine::nlQuiet) cout << "Writing recovery packets" << endl; // Finish computation of the recovery packets and write the headers to disk. if (!WriteRecoveryPacketHeaders()) return eFileIOError; // Finish computing the full file hash values of the source files if (!FinishFileHashComputation()) return eLogicError; } // Fill in all remaining details in the critical packets. if (!FinishCriticalPackets()) return eLogicError; if (noiselevel > CommandLine::nlQuiet) cout << "Writing verification packets" << endl; // Write all other critical packets to disk. if (!WriteCriticalPackets()) return eFileIOError; // Close all files. if (!CloseFiles()) return eFileIOError; if (noiselevel > CommandLine::nlSilent) cout << "Done" << endl; return eSuccess; } // Compute block size from block count or vice versa depending on which was // specified on the command line bool Par2Creator::ComputeBlockSizeAndBlockCount(const list &extrafiles) { // Determine blocksize from sourceblockcount or vice-versa if (blocksize > 0) { u64 count = 0; for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { count += (i->FileSize() + blocksize-1) / blocksize; } if (count > 32768) { cerr << "Block size is too small. It would require " << count << "blocks." << endl; return false; } sourceblockcount = (u32)count; } else if (sourceblockcount > 0) { if (sourceblockcount < extrafiles.size()) { // The block count cannot be less that the number of files. cerr << "Block count is too small." << endl; return false; } else if (sourceblockcount == extrafiles.size()) { // If the block count is the same as the number of files, then the block // size is the size of the largest file (rounded up to a multiple of 4). u64 largestsourcesize = 0; for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { if (largestsourcesize < i->FileSize()) { largestsourcesize = i->FileSize(); } } blocksize = (largestsourcesize + 3) & ~3; } else { u64 totalsize = 0; for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { totalsize += (i->FileSize() + 3) / 4; } if (sourceblockcount > totalsize) { sourceblockcount = (u32)totalsize; blocksize = 4; } else { // Absolute lower bound and upper bound on the source block size that will // result in the requested source block count. u64 lowerBound = totalsize / sourceblockcount; u64 upperBound = (totalsize + sourceblockcount - extrafiles.size() - 1) / (sourceblockcount - extrafiles.size()); u64 bestsize = lowerBound; u64 bestdistance = 1000000; u64 bestcount = 0; u64 count; u64 size; // Work out how many blocks you get for the lower bound block size { size = lowerBound; count = 0; for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { count += ((i->FileSize()+3)/4 + size-1) / size; } if (bestdistance > (count>sourceblockcount ? count-sourceblockcount : sourceblockcount-count)) { bestdistance = (count>sourceblockcount ? count-sourceblockcount : sourceblockcount-count); bestcount = count; bestsize = size; } } // Work out how many blocks you get for the upper bound block size { size = upperBound; count = 0; for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { count += ((i->FileSize()+3)/4 + size-1) / size; } if (bestdistance > (count>sourceblockcount ? count-sourceblockcount : sourceblockcount-count)) { bestdistance = (count>sourceblockcount ? count-sourceblockcount : sourceblockcount-count); bestcount = count; bestsize = size; } } // Use binary search to find best block size while (lowerBound+1 < upperBound) { size = (lowerBound + upperBound)/2; count = 0; for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { count += ((i->FileSize()+3)/4 + size-1) / size; } if (bestdistance > (count>sourceblockcount ? count-sourceblockcount : sourceblockcount-count)) { bestdistance = (count>sourceblockcount ? count-sourceblockcount : sourceblockcount-count); bestcount = count; bestsize = size; } if (count < sourceblockcount) { upperBound = size; } else if (count > sourceblockcount) { lowerBound = size; } else { upperBound = size; } } size = bestsize; count = bestcount; if (count > 32768) { cerr << "Error calculating block size." << endl; return false; } sourceblockcount = (u32)count; blocksize = size*4; } } } return true; } // Determine how many recovery blocks to create based on the source block // count and the requested level of redundancy. bool Par2Creator::ComputeRecoveryBlockCount(u32 redundancy) { // Determine recoveryblockcount recoveryblockcount = (sourceblockcount * redundancy + 50) / 100; // Force valid values if necessary if (recoveryblockcount == 0 && redundancy > 0) recoveryblockcount = 1; if (recoveryblockcount > 65536) { cerr << "Too many recovery blocks requested." << endl; return false; } // Check that the last recovery block number would not be too large if (firstrecoveryblock + recoveryblockcount >= 65536) { cerr << "First recovery block number is too high." << endl; return false; } return true; } // Determine how much recovery data can be computed on one pass bool Par2Creator::CalculateProcessBlockSize(size_t memorylimit) { // Are we computing any recovery blocks if (recoveryblockcount == 0) { deferhashcomputation = false; } else { // Would single pass processing use too much memory if (blocksize * recoveryblockcount > memorylimit) { // Pick a size that is small enough chunksize = ~3 & (memorylimit / recoveryblockcount); deferhashcomputation = false; } else { chunksize = (size_t)blocksize; deferhashcomputation = true; } } return true; } // Determine how many recovery files to create. bool Par2Creator::ComputeRecoveryFileCount(void) { // Are we computing any recovery blocks if (recoveryblockcount == 0) { recoveryfilecount = 0; return true; } switch (recoveryfilescheme) { case CommandLine::scUnknown: { assert(false); return false; } break; case CommandLine::scVariable: case CommandLine::scUniform: { if (recoveryfilecount == 0) { // If none specified then then filecount is roughly log2(blockcount) // This prevents you getting excessively large numbers of files // when the block count is high and also allows the files to have // sizes which vary exponentially. for (u32 blocks=recoveryblockcount; blocks>0; blocks>>=1) { recoveryfilecount++; } } if (recoveryfilecount > recoveryblockcount) { // You cannot have move recovery files that there are recovery blocks // to put in them. cerr << "Too many recovery files specified." << endl; return false; } } break; case CommandLine::scLimited: { // No recovery file will contain more recovery blocks than would // be required to reconstruct the largest source file if it // were missing. Other recovery files will have recovery blocks // distributed in an exponential scheme. u32 largest = (u32)((largestfilesize + blocksize-1) / blocksize); u32 whole = recoveryblockcount / largest; whole = (whole >= 1) ? whole-1 : 0; u32 extra = recoveryblockcount - whole * largest; recoveryfilecount = whole; for (u32 blocks=extra; blocks>0; blocks>>=1) { recoveryfilecount++; } } break; } return true; } // Open all of the source files, compute the Hashes and CRC values, and store // the results in the file verification and file description packets. bool Par2Creator::OpenSourceFiles(const list &extrafiles) { ExtraFileIterator extrafile = extrafiles.begin(); while (extrafile != extrafiles.end()) { Par2CreatorSourceFile *sourcefile = new Par2CreatorSourceFile; string path; string name; DiskFile::SplitFilename(extrafile->FileName(), path, name); if (noiselevel > CommandLine::nlSilent) cout << "Opening: " << name << endl; // Open the source file and compute its Hashes and CRCs. if (!sourcefile->Open(noiselevel, *extrafile, blocksize, deferhashcomputation)) { delete sourcefile; return false; } // Record the file verification and file description packets // in the critical packet list. sourcefile->RecordCriticalPackets(criticalpackets); // Add the source file to the sourcefiles array. sourcefiles.push_back(sourcefile); // Close the source file until its needed sourcefile->Close(); ++extrafile; } return true; } // Create the main packet and determine the setid to use with all packets bool Par2Creator::CreateMainPacket(void) { // Construct the main packet from the list of source files and the block size. mainpacket = new MainPacket; // Add the main packet to the list of critical packets. criticalpackets.push_back(mainpacket); // Create the packet (sourcefiles will get sorted into FileId order). return mainpacket->Create(sourcefiles, blocksize); } // Create the creator packet. bool Par2Creator::CreateCreatorPacket(void) { // Construct the creator packet creatorpacket = new CreatorPacket; // Create the packet return creatorpacket->Create(mainpacket->SetId()); } // Initialise all of the source blocks ready to start reading data from the source files. bool Par2Creator::CreateSourceBlocks(void) { // Allocate the array of source blocks sourceblocks.resize(sourceblockcount); vector::iterator sourceblock = sourceblocks.begin(); for (vector::iterator sourcefile = sourcefiles.begin(); sourcefile!= sourcefiles.end(); sourcefile++) { // Allocate the appopriate number of source blocks to each source file. // sourceblock will be advanced. (*sourcefile)->InitialiseSourceBlocks(sourceblock, blocksize); } return true; } class FileAllocation { public: FileAllocation(void) { filename = ""; exponent = 0; count = 0; } string filename; u32 exponent; u32 count; }; // Create all of the output files and allocate all packets to appropriate file offets. bool Par2Creator::InitialiseOutputFiles(string par2filename) { // Allocate the recovery packets recoverypackets.resize(recoveryblockcount); // Choose filenames and decide which recovery blocks to place in each file vector fileallocations; fileallocations.resize(recoveryfilecount+1); // One extra file with no recovery blocks { // Decide how many recovery blocks to place in each file u32 exponent = firstrecoveryblock; if (recoveryfilecount > 0) { switch (recoveryfilescheme) { case CommandLine::scUnknown: { assert(false); return false; } break; case CommandLine::scUniform: { // Files will have roughly the same number of recovery blocks each. u32 base = recoveryblockcount / recoveryfilecount; u32 remainder = recoveryblockcount % recoveryfilecount; for (u32 filenumber=0; filenumber= 2*largest && filenumber > 0) { filenumber--; exponent -= largest; blocks -= largest; fileallocations[filenumber].exponent = exponent; fileallocations[filenumber].count = largest; } assert(blocks > 0 && filenumber > 0); exponent = firstrecoveryblock; u32 count = 1; u32 files = filenumber; // Allocate exponentially at the bottom for (filenumber=0; filenumber=10; t/=10) { digitsLow++; } u32 digitsCount = 1; for (u32 t=limitCount; t>=10; t/=10) { digitsCount++; } sprintf(filenameformat, "%%s.vol%%0%dd+%%0%dd.par2", digitsLow, digitsCount); } // Set the filenames for (u32 filenumber=0; filenumberSetId(); vector::iterator recoverypacket = recoverypackets.begin(); vector::iterator recoveryfile = recoveryfiles.begin(); vector::iterator fileallocation = fileallocations.begin(); // For each recovery file: while (recoveryfile != recoveryfiles.end()) { // How many recovery blocks in this file u32 count = fileallocation->count; // start at the beginning of the recovery file u64 offset = 0; if (count == 0) { // Write one set of critical packets list::const_iterator nextCriticalPacket = criticalpackets.begin(); while (nextCriticalPacket != criticalpackets.end()) { criticalpacketentries.push_back(CriticalPacketEntry(&*recoveryfile, offset, *nextCriticalPacket)); offset += (*nextCriticalPacket)->PacketLength(); ++nextCriticalPacket; } } else { // How many copies of each critical packet u32 copies = 0; for (u32 t=count; t>0; t>>=1) { copies++; } // Get ready to iterate through the critical packets u32 packetCount = 0; list::const_iterator nextCriticalPacket = criticalpackets.end(); // What is the first exponent u32 exponent = fileallocation->exponent; // Start allocating the recovery packets u32 limit = exponent + count; while (exponent < limit) { // Add the next recovery packet recoverypacket->Create(&*recoveryfile, offset, blocksize, exponent, setid); offset += recoverypacket->PacketLength(); ++recoverypacket; ++exponent; // Add some critical packets packetCount += copies * criticalpackets.size(); while (packetCount >= count) { if (nextCriticalPacket == criticalpackets.end()) nextCriticalPacket = criticalpackets.begin(); criticalpacketentries.push_back(CriticalPacketEntry(&*recoveryfile, offset, *nextCriticalPacket)); offset += (*nextCriticalPacket)->PacketLength(); ++nextCriticalPacket; packetCount -= count; } } } // Add one copy of the creator packet criticalpacketentries.push_back(CriticalPacketEntry(&*recoveryfile, offset, creatorpacket)); offset += creatorpacket->PacketLength(); // Create the file on disk and make it the required size if (!recoveryfile->Create(fileallocation->filename, offset)) return false; ++recoveryfile; ++fileallocation; } } } return true; } // Allocate memory buffers for reading and writing data to disk. bool Par2Creator::AllocateBuffers(void) { inputbuffer = new u8[chunksize]; outputbuffer = new u8[chunksize * recoveryblockcount]; if (inputbuffer == NULL || outputbuffer == NULL) { cerr << "Could not allocate buffer memory." << endl; return false; } return true; } // Compute the Reed Solomon matrix bool Par2Creator::ComputeRSMatrix(void) { // Set the number of input blocks if (!rs.SetInput(sourceblockcount)) return false; // Set the number of output blocks to be created if (!rs.SetOutput(false, (u16)firstrecoveryblock, (u16)firstrecoveryblock + (u16)(recoveryblockcount-1))) return false; // Compute the RS matrix if (!rs.Compute(noiselevel)) return false; return true; } // Read source data, process it through the RS matrix and write it to disk. bool Par2Creator::ProcessData(u64 blockoffset, size_t blocklength) { // Clear the output buffer memset(outputbuffer, 0, chunksize * recoveryblockcount); // If we have defered computation of the file hash and block crc and hashes // sourcefile and sourceindex will be used to update them during // the main recovery block computation vector::iterator sourcefile = sourcefiles.begin(); u32 sourceindex = 0; vector::iterator sourceblock; u32 inputblock; DiskFile *lastopenfile = NULL; // For each input block for ((sourceblock=sourceblocks.begin()),(inputblock=0); sourceblock != sourceblocks.end(); ++sourceblock, ++inputblock) { // Are we reading from a new file? if (lastopenfile != (*sourceblock).GetDiskFile()) { // Close the last file if (lastopenfile != NULL) { lastopenfile->Close(); } // Open the new file lastopenfile = (*sourceblock).GetDiskFile(); if (!lastopenfile->Open()) { return false; } } // Read data from the current input block if (!sourceblock->ReadData(blockoffset, blocklength, inputbuffer)) return false; if (deferhashcomputation) { assert(blockoffset == 0 && blocklength == blocksize); assert(sourcefile != sourcefiles.end()); (*sourcefile)->UpdateHashes(sourceindex, inputbuffer, blocklength); } // For each output block for (u32 outputblock=0; outputblock CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * progress / totaldata); progress += blocklength; u32 newfraction = (u32)(1000 * progress / totaldata); if (oldfraction != newfraction) { cout << "Processing: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } } // Work out which source file the next block belongs to if (++sourceindex >= (*sourcefile)->BlockCount()) { sourceindex = 0; ++sourcefile; } } // Close the last file if (lastopenfile != NULL) { lastopenfile->Close(); } if (noiselevel > CommandLine::nlQuiet) cout << "Writing recovery packets\r"; // For each output block for (u32 outputblock=0; outputblock CommandLine::nlQuiet) cout << "Wrote " << recoveryblockcount * blocklength << " bytes to disk" << endl; return true; } // Finish computation of the recovery packets and write the headers to disk. bool Par2Creator::WriteRecoveryPacketHeaders(void) { // For each recovery packet for (vector::iterator recoverypacket = recoverypackets.begin(); recoverypacket != recoverypackets.end(); ++recoverypacket) { // Finish the packet header and write it to disk if (!recoverypacket->WriteHeader()) return false; } return true; } bool Par2Creator::FinishFileHashComputation(void) { // If we defered the computation of the full file hash, then we finish it now if (deferhashcomputation) { // For each source file vector::iterator sourcefile = sourcefiles.begin(); while (sourcefile != sourcefiles.end()) { (*sourcefile)->FinishHashes(); ++sourcefile; } } return true; } // Fill in all remaining details in the critical packets. bool Par2Creator::FinishCriticalPackets(void) { // Get the setid from the main packet const MD5Hash &setid = mainpacket->SetId(); for (list::iterator criticalpacket=criticalpackets.begin(); criticalpacket!=criticalpackets.end(); criticalpacket++) { // Store the setid in each of the critical packets // and compute the packet_hash of each one. (*criticalpacket)->FinishPacket(setid); } return true; } // Write all other critical packets to disk. bool Par2Creator::WriteCriticalPackets(void) { list::const_iterator packetentry = criticalpacketentries.begin(); // For each critical packet while (packetentry != criticalpacketentries.end()) { // Write it to disk if (!packetentry->WritePacket()) return false; ++packetentry; } return true; } // Close all files. bool Par2Creator::CloseFiles(void) { // // Close each source file. // for (vector::iterator sourcefile = sourcefiles.begin(); // sourcefile != sourcefiles.end(); // ++sourcefile) // { // (*sourcefile)->Close(); // } // Close each recovery file. for (vector::iterator recoveryfile = recoveryfiles.begin(); recoveryfile != recoveryfiles.end(); ++recoveryfile) { recoveryfile->Close(); } return true; } par2cmdline-0.4/par2creator.h0000644000000000000000000001337710037504610011610 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR2CREATOR_H__ #define __PAR2CREATOR_H__ class MainPacket; class CreatorPacket; class CriticalPacket; class Par2Creator { public: Par2Creator(void); ~Par2Creator(void); // Create recovery files from the source files specified on the command line Result Process(const CommandLine &commandline); protected: // Steps in the creation process: // Compute block size from block count or vice versa depending on which was // specified on the command line bool ComputeBlockSizeAndBlockCount(const list &extrafiles); // Determine how many recovery blocks to create based on the source block // count and the requested level of redundancy. bool ComputeRecoveryBlockCount(u32 redundancy); // Determine how much recovery data can be computed on one pass bool CalculateProcessBlockSize(size_t memorylimit); // Determine how many recovery files to create. bool ComputeRecoveryFileCount(void); // Open all of the source files, compute the Hashes and CRC values, and store // the results in the file verification and file description packets. bool OpenSourceFiles(const list &extrafiles); // Create the main packet and determine the set_id_hash to use with all packets bool CreateMainPacket(void); // Create the creator packet. bool CreateCreatorPacket(void); // Initialise all of the source blocks ready to start reading data from the source files. bool CreateSourceBlocks(void); // Create all of the output files and allocate all packets to appropriate file offets. bool InitialiseOutputFiles(string par2filename); // Allocate memory buffers for reading and writing data to disk. bool AllocateBuffers(void); // Compute the Reed Solomon matrix bool ComputeRSMatrix(void); // Read source data, process it through the RS matrix and write it to disk. bool ProcessData(u64 blockoffset, size_t blocklength); // Finish computation of the recovery packets and write the headers to disk. bool WriteRecoveryPacketHeaders(void); // Finish computing the full file hash values of the source files bool FinishFileHashComputation(void); // Fill in all remaining details in the critical packets. bool FinishCriticalPackets(void); // Write all other critical packets to disk. bool WriteCriticalPackets(void); // Close all files. bool CloseFiles(void); protected: CommandLine::NoiseLevel noiselevel; // How noisy we should be u64 blocksize; // The size of each block. size_t chunksize; // How much of each block will be processed at a // time (due to memory constraints). void *inputbuffer; // chunksize void *outputbuffer; // chunksize * recoveryblockcount u32 sourcefilecount; // Number of source files for which recovery data will be computed. u32 sourceblockcount; // Total number of data blocks that the source files will be // virtualy sliced into. u64 largestfilesize; // The size of the largest source file CommandLine::Scheme recoveryfilescheme; // What scheme will be used to select the // sizes for the recovery files. u32 recoveryfilecount; // The number of recovery files that will be created u32 recoveryblockcount; // The number of recovery blocks that will be placed // in the recovery files. u32 firstrecoveryblock; // The lowest exponent value to use for the recovery blocks. MainPacket *mainpacket; // The main packet CreatorPacket *creatorpacket; // The creator packet vector sourcefiles; // Array containing details of the source files // as well as the file verification and file // description packets for them. vector sourceblocks; // Array with one entry for every source block. vector recoveryfiles; // Array with one entry for every recovery file. vector recoverypackets; // Array with one entry for every recovery packet. list criticalpackets; // A list of all of the critical packets. list criticalpacketentries; // A list of which critical packet will // be written to which recovery file. ReedSolomon rs; // The Reed Solomon matrix. u64 progress; // How much data has been processed. u64 totaldata; // Total amount of data to be processed. bool deferhashcomputation; // If we have enough memory to compute all recovery data // in one pass, then we can defer the computation of // the full file hash and block crc and hashes until // the recovery data is computed. }; #endif // __PAR2CREATOR_H__ par2cmdline-0.4/par2creatorsourcefile.cpp0000644000000000000000000002362310037510763014225 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif Par2CreatorSourceFile::Par2CreatorSourceFile(void) { descriptionpacket = 0; verificationpacket = 0; diskfile = 0; blockcount = 0; //diskfilename; //parfilename; contextfull = 0; } Par2CreatorSourceFile::~Par2CreatorSourceFile(void) { delete descriptionpacket; delete verificationpacket; delete diskfile; delete contextfull; } // Open the source file, compute the MD5 Hash of the whole file and the first // 16k of the file, and then compute the FileId and store the results // in a file description packet and a file verification packet. bool Par2CreatorSourceFile::Open(CommandLine::NoiseLevel noiselevel, const CommandLine::ExtraFile &extrafile, u64 blocksize, bool deferhashcomputation) { // Get the filename and filesize diskfilename = extrafile.FileName(); filesize = extrafile.FileSize(); // Work out how many blocks the file will be sliced into blockcount = (u32)((filesize + blocksize-1) / blocksize); // Determine what filename to record in the PAR2 files string::size_type where; if (string::npos != (where = diskfilename.find_last_of('\\')) || string::npos != (where = diskfilename.find_last_of('/'))) { parfilename = diskfilename.substr(where+1); } else { parfilename = diskfilename; } // Create the Description and Verification packets descriptionpacket = new DescriptionPacket; descriptionpacket->Create(parfilename, filesize); verificationpacket = new VerificationPacket; verificationpacket->Create(blockcount); // Create the diskfile object diskfile = new DiskFile; // Open the source file if (!diskfile->Open(diskfilename, filesize)) return false; // Do we want to defer the computation of the full file hash, and // the block crc and hashes. This is only permitted if there // is sufficient memory available to create all recovery blocks // in one pass of the source files (i.e. chunksize == blocksize) if (deferhashcomputation) { // Initialise a buffer to read the first 16k of the source file size_t buffersize = 16 * 1024; if (buffersize > filesize) buffersize = (size_t)filesize; char *buffer = new char[buffersize]; // Read the data from the file if (!diskfile->Read(0, buffer, buffersize)) { diskfile->Close(); delete [] buffer; return false; } // Compute the hash of the data read from the file MD5Context context; context.Update(buffer, buffersize); delete [] buffer; MD5Hash hash; context.Final(hash); // Store the hash in the descriptionpacket and compute the file id descriptionpacket->Hash16k(hash); // Compute the fileid and store it in the verification packet. descriptionpacket->ComputeFileId(); verificationpacket->FileId(descriptionpacket->FileId()); // Allocate an MD5 context for computing the file hash // during the recovery data generation phase contextfull = new MD5Context; } else { // Initialise a buffer to read the source file size_t buffersize = 1024*1024; if (buffersize > min(blocksize,filesize)) buffersize = (size_t)min(blocksize,filesize); char *buffer = new char[buffersize]; // Get ready to start reading source file to compute the hashes and crcs u64 offset = 0; u32 blocknumber = 0; u64 need = blocksize; MD5Context filecontext; MD5Context blockcontext; u32 blockcrc = 0; // Whilst we have not reached the end of the file while (offset < filesize) { // Work out how much we can read size_t want = (size_t)min(filesize-offset, (u64)buffersize); // Read some data from the file into the buffer if (!diskfile->Read(offset, buffer, want)) { diskfile->Close(); delete [] buffer; return false; } // If the new data passes the 16k boundary, compute the 16k hash for the file if (offset < 16384 && offset + want >= 16384) { filecontext.Update(buffer, (size_t)(16384-offset)); MD5Context temp = filecontext; MD5Hash hash; temp.Final(hash); // Store the 16k hash in the file description packet descriptionpacket->Hash16k(hash); if (offset + want > 16384) { filecontext.Update(&buffer[16384-offset], (size_t)(offset+want)-16384); } } else { filecontext.Update(buffer, want); } // Get ready to update block hashes and crcs u32 used = 0; // Whilst we have not used all of the data we just read while (used < want) { // How much of it can we use for the current block u32 use = (u32)min(need, (u64)(want-used)); blockcrc = ~0 ^ CRCUpdateBlock(~0 ^ blockcrc, use, &buffer[used]); blockcontext.Update(&buffer[used], use); used += use; need -= use; // Have we finished the current block if (need == 0) { MD5Hash blockhash; blockcontext.Final(blockhash); // Store the block hash and block crc in the file verification packet. verificationpacket->SetBlockHashAndCRC(blocknumber, blockhash, blockcrc); blocknumber++; // More blocks if (blocknumber < blockcount) { need = blocksize; blockcontext.Reset(); blockcrc = 0; } } } if (noiselevel > CommandLine::nlQuiet) { // Display progress u32 oldfraction = (u32)(1000 * offset / filesize); offset += want; u32 newfraction = (u32)(1000 * offset / filesize); if (oldfraction != newfraction) { cout << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } } // Did we finish the last block if (need > 0) { blockcrc = ~0 ^ CRCUpdateBlock(~0 ^ blockcrc, (size_t)need); blockcontext.Update((size_t)need); MD5Hash blockhash; blockcontext.Final(blockhash); // Store the block hash and block crc in the file verification packet. verificationpacket->SetBlockHashAndCRC(blocknumber, blockhash, blockcrc); blocknumber++; need = 0; } // Finish computing the file hash. MD5Hash filehash; filecontext.Final(filehash); // Store the file hash in the file description packet. descriptionpacket->HashFull(filehash); // Did we compute the 16k hash. if (offset < 16384) { // Store the 16k hash in the file description packet. descriptionpacket->Hash16k(filehash); } delete [] buffer; // Compute the fileid and store it in the verification packet. descriptionpacket->ComputeFileId(); verificationpacket->FileId(descriptionpacket->FileId()); } return true; } void Par2CreatorSourceFile::Close(void) { diskfile->Close(); } void Par2CreatorSourceFile::RecordCriticalPackets(list &criticalpackets) { // Add the file description packet and file verification packet to // the critical packet list. criticalpackets.push_back(descriptionpacket); criticalpackets.push_back(verificationpacket); } bool Par2CreatorSourceFile::CompareLess(const Par2CreatorSourceFile* const &left, const Par2CreatorSourceFile* const &right) { // Sort source files based on fileid return left->descriptionpacket->FileId() < right->descriptionpacket->FileId(); } const MD5Hash& Par2CreatorSourceFile::FileId(void) const { // Get the file id hash return descriptionpacket->FileId(); } void Par2CreatorSourceFile::InitialiseSourceBlocks(vector::iterator &sourceblock, u64 blocksize) { for (u32 blocknum=0; blocknumSetLocation(diskfile, // file blocknum * blocksize); // offset sourceblock->SetLength(min(blocksize, filesize - (u64)blocknum * blocksize)); // length sourceblock++; } } void Par2CreatorSourceFile::UpdateHashes(u32 blocknumber, const void *buffer, size_t length) { // Compute the crc and hash of the data u32 blockcrc = ~0 ^ CRCUpdateBlock(~0, length, buffer); MD5Context blockcontext; blockcontext.Update(buffer, length); MD5Hash blockhash; blockcontext.Final(blockhash); // Store the results in the verification packet verificationpacket->SetBlockHashAndCRC(blocknumber, blockhash, blockcrc); // Update the full file hash, but don't go beyond the end of the file if (length > filesize - blocknumber * length) { length = (size_t)(filesize - blocknumber * (u64)length); } assert(contextfull != 0); contextfull->Update(buffer, length); } void Par2CreatorSourceFile::FinishHashes(void) { assert(contextfull != 0); // Finish computation of the full file hash MD5Hash hash; contextfull->Final(hash); // Store it in the description packet descriptionpacket->HashFull(hash); } par2cmdline-0.4/par2creatorsourcefile.h0000644000000000000000000000615010037511014013654 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR2CREATORSOURCEFILE_H__ #define __PAR2CREATORSOURCEFILE_H__ class DescriptionPacket; class VerificationPacket; class DiskFile; // The Par2CreatorSourceFile contains the file verification and file description // packet for one source file. class Par2CreatorSourceFile { private: // Don't permit copying or assignment Par2CreatorSourceFile(const Par2CreatorSourceFile &other); Par2CreatorSourceFile& operator=(const Par2CreatorSourceFile &other); public: Par2CreatorSourceFile(void); ~Par2CreatorSourceFile(void); // Open the source file and compute the Hashes and CRCs. bool Open(CommandLine::NoiseLevel noiselevel, const CommandLine::ExtraFile &extrafile, u64 blocksize, bool deferhashcomputation); void Close(void); // Recover the file description and file verification packets // in the critical packet list. void RecordCriticalPackets(list &criticalpackets); // Get the file id const MD5Hash& FileId(void) const; // Sort source files based on the file id hash static bool CompareLess(const Par2CreatorSourceFile* const &left, const Par2CreatorSourceFile* const &right); // Allocate the appropriate number of source blocks to the source file void InitialiseSourceBlocks(vector::iterator &sourceblock, u64 blocksize); // Update the file hash and the block crc and hashes void UpdateHashes(u32 blocknumber, const void *buffer, size_t length); // Finish computation of the file hash void FinishHashes(void); // How many blocks does this source file use u32 BlockCount(void) const {return blockcount;} protected: DescriptionPacket *descriptionpacket; // The file description packet. VerificationPacket *verificationpacket; // The file verification packet. DiskFile *diskfile; // The source file u64 filesize; // The size of the source file. string diskfilename; // The filename of the source file on disk. string parfilename; // The filename that will be recorded in the file description packet. u32 blockcount; // How many blocks the file will be divided into. MD5Context *contextfull; // MD5 context used to calculate the hash of the whole file }; #endif // __PAR2CREATORSOURCEFILE_H__ par2cmdline-0.4/par2fileformat.cpp0000644000000000000000000000325307664453165012650 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" MAGIC packet_magic = {{'P', 'A', 'R', '2', '\0','P', 'K', 'T'}}; PACKETTYPE fileverificationpacket_type = {{'P', 'A', 'R', ' ', '2', '.', '0', '\0', 'I', 'F', 'S', 'C', '\0','\0','\0','\0'}}; PACKETTYPE filedescriptionpacket_type = {{'P', 'A', 'R', ' ', '2', '.', '0', '\0', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c' }}; PACKETTYPE mainpacket_type = {{'P', 'A', 'R', ' ', '2', '.', '0', '\0', 'M', 'a', 'i', 'n', '\0','\0','\0','\0'}}; PACKETTYPE recoveryblockpacket_type = {{'P', 'A', 'R', ' ', '2', '.', '0', '\0', 'R', 'e', 'c', 'v', 'S', 'l', 'i', 'c' }}; PACKETTYPE creatorpacket_type = {{'P', 'A', 'R', ' ', '2', '.', '0', '\0', 'C', 'r', 'e', 'a', 't', 'o', 'r', '\0'}}; par2cmdline-0.4/par2fileformat.h0000644000000000000000000001567407712575454012327 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR2FILEFORMAT_H__ #define __PAR2FILEFORMAT_H__ // This file defines the format of a PAR2 file. // PAR2 files consist of one or more "packets" that contain information // that is required to be able to verify and repair damaged data files. // All packets start with a short "header" which contains information // used to describe what sort of data is stored in the rest of the packet // and also to allow that data to be verified. // This file details the format for the following packet types described // in the PAR 2.0 specification: // Main Packet struct MAINPACKET // File Description Packet struct FILEDESCRIPTIONPACKET // Input File Slice Checksum Packet struct FILEVERIFICATIONPACKET // Recovery Slice Packet struct RECOVERYBLOCKPACKET // Creator Packet struct CREATORPACKET #ifdef WIN32 #pragma pack(push, 1) #define PACKED #else #define PACKED __attribute__ ((packed)) #endif #ifdef _MSC_VER #pragma warning(disable:4200) #endif // All numeric fields in the file format are in LITTLE ENDIAN format. // The types leu32 and leu64 are defined in letype.h // Two simple types used in the packet header. struct MAGIC {u8 magic[8];} PACKED; struct PACKETTYPE {u8 type[16];} PACKED; // Every packet starts with a packet header. struct PACKET_HEADER { // Header MAGIC magic; // = {'P', 'A', 'R', '2', '\0', 'P', 'K', 'T'} leu64 length; // Length of entire packet including header MD5Hash hash; // Hash of entire packet excepting the first 3 fields MD5Hash setid; // Normally computed as the Hash of body of "Main Packet" PACKETTYPE type; // Used to specify the meaning of the rest of the packet } PACKED; // The file verification packet is used to determine whether or not any // parts of a damaged file are useable. // It contains a FileId used to pair it with a corresponding file description // packet, followed by an array of hash and crc values. The number of entries in // the array can be determined from the packet_length. struct FILEVERIFICATIONENTRY { MD5Hash hash; leu32 crc; } PACKED; struct FILEVERIFICATIONPACKET { PACKET_HEADER header; // Body MD5Hash fileid; // MD5hash of file_hash_16k, file_length, file_name FILEVERIFICATIONENTRY entries[]; } PACKED; // The file description packet is used to record the name of the file, // its size, and the Hash of both the whole file and the first 16k of // the file. // If the name of the file is an exact multiple of 4 characters in length // then it may not have a NULL termination. If the name of the file is not // an exact multiple of 4, then it will be padded with 0 bytes at the // end to make it up to a multiple of 4. struct FILEDESCRIPTIONPACKET { PACKET_HEADER header; // Body MD5Hash fileid; // MD5hash of [hash16k, length, name] MD5Hash hashfull; // MD5 Hash of the whole file MD5Hash hash16k; // MD5 Hash of the first 16k of the file leu64 length; // Length of the file u8 name[]; // Name of the file, padded with 1 to 3 zero bytes to reach // a multiple of 4 bytes. // Actual length can be determined from overall packet // length and then working backwards to find the first non // zero character. //u8* name(void) {return (u8*)&this[1];} //const u8* name(void) const {return (const u8*)&this[1];} } PACKED; // The main packet is used to tie together the other packets in a recovery file. // It specifies the block size used to virtually slice the source files, a count // of the number of source files, and an array of Hash values used to specify // in what order the source files are processed. // Each entry in the fileid array corresponds with the fileid value // in a file description packet and a file verification packet. // The fileid array may contain more entries than the count of the number // of recoverable files. The extra entries correspond to files that were not // used during the creation of the recovery files and which may not therefore // be repaired if they are found to be damaged. struct MAINPACKET { PACKET_HEADER header; // Body leu64 blocksize; leu32 recoverablefilecount; MD5Hash fileid[0]; //MD5Hash* fileid(void) {return (MD5Hash*)&this[1];} //const MD5Hash* fileid(void) const {return (const MD5Hash*)&this[1];} } PACKED; // The creator packet is used to identify which program created a particular // recovery file. It is not required for verification or recovery of damaged // files. struct CREATORPACKET { PACKET_HEADER header; // Body u8 client[]; //u8* client(void) {return (u8*)&this[1];} } PACKED; // The recovery block packet contains a single block of recovery data along // with the exponent value used during the computation of that block. struct RECOVERYBLOCKPACKET { PACKET_HEADER header; // Body leu32 exponent; // unsigned long data[]; // unsigned long* data(void) {return (unsigned long*)&this[1];} } PACKED; #ifdef _MSC_VER #pragma warning(default:4200) #endif #ifdef WIN32 #pragma pack(pop) #endif #undef PACKED // Operators for comparing the MAGIC and PACKETTYPE values inline bool operator == (const MAGIC &left, const MAGIC &right) { return (0==memcmp(&left, &right, sizeof(left))); } inline bool operator != (const MAGIC &left, const MAGIC &right) { return !operator==(left, right); } inline bool operator == (const PACKETTYPE &left, const PACKETTYPE &right) { return (0==memcmp(&left, &right, sizeof(left))); } inline bool operator != (const PACKETTYPE &left, const PACKETTYPE &right) { return !operator==(left, right); } extern MAGIC packet_magic; extern PACKETTYPE fileverificationpacket_type; extern PACKETTYPE filedescriptionpacket_type; extern PACKETTYPE mainpacket_type; extern PACKETTYPE recoveryblockpacket_type; extern PACKETTYPE creatorpacket_type; #endif //__PAR2FILEFORMAT_H__ par2cmdline-0.4/par2repairer.cpp0000755000000000000000000020010610037510530012302 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif Par2Repairer::Par2Repairer(void) { firstpacket = true; mainpacket = 0; creatorpacket = 0; blocksize = 0; sourceblockcount = 0; blocksallocated = false; availableblockcount = 0; missingblockcount = 0; completefilecount = 0; renamedfilecount = 0; damagedfilecount = 0; missingfilecount = 0; inputbuffer = 0; outputbuffer = 0; noiselevel = CommandLine::nlNormal; } Par2Repairer::~Par2Repairer(void) { delete [] (u8*)inputbuffer; delete [] (u8*)outputbuffer; map::iterator rp = recoverypacketmap.begin(); while (rp != recoverypacketmap.end()) { delete (*rp).second; ++rp; } map::iterator sf = sourcefilemap.begin(); while (sf != sourcefilemap.end()) { Par2RepairerSourceFile *sourcefile = (*sf).second; delete sourcefile; ++sf; } delete mainpacket; delete creatorpacket; } Result Par2Repairer::Process(const CommandLine &commandline, bool dorepair) { // What noiselevel are we using noiselevel = commandline.GetNoiseLevel(); // Get filesnames from the command line string par2filename = commandline.GetParFilename(); const list &extrafiles = commandline.GetExtraFiles(); // Determine the searchpath from the location of the main PAR2 file string name; DiskFile::SplitFilename(par2filename, searchpath, name); // Load packets from the main PAR2 file if (!LoadPacketsFromFile(searchpath + name)) return eLogicError; // Load packets from other PAR2 files with names based on the original PAR2 file if (!LoadPacketsFromOtherFiles(par2filename)) return eLogicError; // Load packets from any other PAR2 files whose names are given on the command line if (!LoadPacketsFromExtraFiles(extrafiles)) return eLogicError; if (noiselevel > CommandLine::nlQuiet) cout << endl; // Check that the packets are consistent and discard any that are not if (!CheckPacketConsistency()) return eInsufficientCriticalData; // Use the information in the main packet to get the source files // into the correct order and determine their filenames if (!CreateSourceFileList()) return eLogicError; // Determine the total number of DataBlocks for the recoverable source files // The allocate the DataBlocks and assign them to each source file if (!AllocateSourceBlocks()) return eLogicError; // Create a verification hash table for all files for which we have not // found a complete version of the file and for which we have // a verification packet if (!PrepareVerificationHashTable()) return eLogicError; // Compute the table for the sliding CRC computation if (!ComputeWindowTable()) return eLogicError; if (noiselevel > CommandLine::nlQuiet) cout << endl << "Verifying source files:" << endl << endl; // Attempt to verify all of the source files if (!VerifySourceFiles()) return eFileIOError; if (completefilecountRecoverableFileCount()) { if (noiselevel > CommandLine::nlQuiet) cout << endl << "Scanning extra files:" << endl << endl; // Scan any extra files specified on the command line if (!VerifyExtraFiles(extrafiles)) return eLogicError; } // Find out how much data we have found UpdateVerificationResults(); if (noiselevel > CommandLine::nlSilent) cout << endl; // Check the verification results and report the results if (!CheckVerificationResults()) return eRepairNotPossible; // Are any of the files incomplete if (completefilecountRecoverableFileCount()) { // Do we want to carry out a repair if (dorepair) { if (noiselevel > CommandLine::nlSilent) cout << endl; // Rename any damaged or missnamed target files. if (!RenameTargetFiles()) return eFileIOError; // Are we still missing any files if (completefilecountRecoverableFileCount()) { // Work out which files are being repaired, create them, and allocate // target DataBlocks to them, and remember them for later verification. if (!CreateTargetFiles()) return eFileIOError; // Work out which data blocks are available, which need to be copied // directly to the output, and which need to be recreated, and compute // the appropriate Reed Solomon matrix. if (!ComputeRSmatrix()) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } if (noiselevel > CommandLine::nlSilent) cout << endl; // Allocate memory buffers for reading and writing data to disk. if (!AllocateBuffers(commandline.GetMemoryLimit())) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eMemoryError; } // Set the total amount of data to be processed. progress = 0; totaldata = blocksize * sourceblockcount * (missingblockcount > 0 ? missingblockcount : 1); // Start at an offset of 0 within a block. u64 blockoffset = 0; while (blockoffset < blocksize) // Continue until the end of the block. { // Work out how much data to process this time. size_t blocklength = (size_t)min((u64)chunksize, blocksize-blockoffset); // Read source data, process it through the RS matrix and write it to disk. if (!ProcessData(blockoffset, blocklength)) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } // Advance to the need offset within each block blockoffset += blocklength; } if (noiselevel > CommandLine::nlSilent) cout << endl << "Verifying repaired files:" << endl << endl; // Verify that all of the reconstructed target files are now correct if (!VerifyTargetFiles()) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } } // Are all of the target files now complete? if (completefilecountRecoverableFileCount()) { cerr << "Repair Failed." << endl; return eRepairFailed; } else { if (noiselevel > CommandLine::nlSilent) cout << endl << "Repair complete." << endl; } } else { return eRepairPossible; } } return eSuccess; } // Load the packets from the specified file bool Par2Repairer::LoadPacketsFromFile(string filename) { // Skip the file if it has already been processed if (diskFileMap.Find(filename) != 0) { return true; } DiskFile *diskfile = new DiskFile; // Open the file if (!diskfile->Open(filename)) { // If we could not open the file, ignore the error and // proceed to the next file delete diskfile; return true; } if (noiselevel > CommandLine::nlSilent) { string path; string name; DiskFile::SplitFilename(filename, path, name); cout << "Loading \"" << name << "\"." << endl; } // How many useable packets have we found u32 packets = 0; // How many recovery packets were there u32 recoverypackets = 0; // How big is the file u64 filesize = diskfile->FileSize(); if (filesize > 0) { // Allocate a buffer to read data into // The buffer should be large enough to hold a whole // critical packet (i.e. file verification, file description, main, // and creator), but not necessarily a whole recovery packet. size_t buffersize = (size_t)min((u64)1048576, filesize); u8 *buffer = new u8[buffersize]; // Progress indicator u64 progress = 0; // Start at the beginning of the file u64 offset = 0; // Continue as long as there is at least enough for the packet header while (offset + sizeof(PACKET_HEADER) <= filesize) { if (noiselevel > CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * progress / filesize); u32 newfraction = (u32)(1000 * offset / filesize); if (oldfraction != newfraction) { cout << "Loading: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; progress = offset; } } // Attempt to read the next packet header PACKET_HEADER header; if (!diskfile->Read(offset, &header, sizeof(header))) break; // Does this look like it might be a packet if (packet_magic != header.magic) { offset++; // Is there still enough for at least a whole packet header while (offset + sizeof(PACKET_HEADER) <= filesize) { // How much can we read into the buffer size_t want = (size_t)min((u64)buffersize, filesize-offset); // Fill the buffer if (!diskfile->Read(offset, buffer, want)) { offset = filesize; break; } // Scan the buffer for the magic value u8 *current = buffer; u8 *limit = &buffer[want-sizeof(PACKET_HEADER)]; while (current <= limit && packet_magic != ((PACKET_HEADER*)current)->magic) { current++; } // What file offset did we reach offset += current-buffer; // Did we find the magic if (current <= limit) { memcpy(&header, current, sizeof(header)); break; } } // Did we reach the end of the file if (offset + sizeof(PACKET_HEADER) > filesize) { break; } } // We have found the magic // Check the packet length if (sizeof(PACKET_HEADER) > header.length || // packet length is too small 0 != (header.length & 3) || // packet length is not a multiple of 4 filesize < offset + header.length) // packet would extend beyond the end of the file { offset++; continue; } // Compute the MD5 Hash of the packet MD5Context context; context.Update(&header.setid, sizeof(header)-offsetof(PACKET_HEADER, setid)); // How much more do I need to read to get the whole packet u64 current = offset+sizeof(PACKET_HEADER); u64 limit = offset+header.length; while (current < limit) { size_t want = (size_t)min((u64)buffersize, limit-current); if (!diskfile->Read(current, buffer, want)) break; context.Update(buffer, want); current += want; } // Did the whole packet get processed if (currentClose(); // Did we actually find any interesting packets if (packets > 0) { if (noiselevel > CommandLine::nlQuiet) { cout << "Loaded " << packets << " new packets"; if (recoverypackets > 0) cout << " including " << recoverypackets << " recovery blocks"; cout << endl; } // Remember that the file was processed bool success = diskFileMap.Insert(diskfile); assert(success); } else { if (noiselevel > CommandLine::nlQuiet) cout << "No new packets found" << endl; delete diskfile; } return true; } // Finish loading a recovery packet bool Par2Repairer::LoadRecoveryPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { RecoveryPacket *packet = new RecoveryPacket; // Load the packet from disk if (!packet->Load(diskfile, offset, header)) { delete packet; return false; } // What is the exponent value of this recovery packet u32 exponent = packet->Exponent(); // Try to insert the new packet into the recovery packet map pair::const_iterator, bool> location = recoverypacketmap.insert(pair(exponent, packet)); // Did the insert fail if (!location.second) { // The packet must be a duplicate of one we already have delete packet; return false; } return true; } // Finish loading a file description packet bool Par2Repairer::LoadDescriptionPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { DescriptionPacket *packet = new DescriptionPacket; // Load the packet from disk if (!packet->Load(diskfile, offset, header)) { delete packet; return false; } // What is the fileid const MD5Hash &fileid = packet->FileId(); // Look up the fileid in the source file map for an existing source file entry map::iterator sfmi = sourcefilemap.find(fileid); Par2RepairerSourceFile *sourcefile = (sfmi == sourcefilemap.end()) ? 0 :sfmi->second; // Was there an existing source file if (sourcefile) { // Does the source file already have a description packet if (sourcefile->GetDescriptionPacket()) { // Yes. We don't need another copy delete packet; return false; } else { // No. Store the packet in the source file sourcefile->SetDescriptionPacket(packet); return true; } } else { // Create a new source file for the packet sourcefile = new Par2RepairerSourceFile(packet, NULL); // Record the source file in the source file map sourcefilemap.insert(pair(fileid, sourcefile)); return true; } } // Finish loading a file verification packet bool Par2Repairer::LoadVerificationPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { VerificationPacket *packet = new VerificationPacket; // Load the packet from disk if (!packet->Load(diskfile, offset, header)) { delete packet; return false; } // What is the fileid const MD5Hash &fileid = packet->FileId(); // Look up the fileid in the source file map for an existing source file entry map::iterator sfmi = sourcefilemap.find(fileid); Par2RepairerSourceFile *sourcefile = (sfmi == sourcefilemap.end()) ? 0 :sfmi->second; // Was there an existing source file if (sourcefile) { // Does the source file already have a verification packet if (sourcefile->GetVerificationPacket()) { // Yes. We don't need another copy. delete packet; return false; } else { // No. Store the packet in the source file sourcefile->SetVerificationPacket(packet); return true; } } else { // Create a new source file for the packet sourcefile = new Par2RepairerSourceFile(NULL, packet); // Record the source file in the source file map sourcefilemap.insert(pair(fileid, sourcefile)); return true; } } // Finish loading the main packet bool Par2Repairer::LoadMainPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { // Do we already have a main packet if (0 != mainpacket) return false; MainPacket *packet = new MainPacket; // Load the packet from disk; if (!packet->Load(diskfile, offset, header)) { delete packet; return false; } mainpacket = packet; return true; } // Finish loading the creator packet bool Par2Repairer::LoadCreatorPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { // Do we already have a creator packet if (0 != creatorpacket) return false; CreatorPacket *packet = new CreatorPacket; // Load the packet from disk; if (!packet->Load(diskfile, offset, header)) { delete packet; return false; } creatorpacket = packet; return true; } // Load packets from other PAR2 files with names based on the original PAR2 file bool Par2Repairer::LoadPacketsFromOtherFiles(string filename) { // Split the original PAR2 filename into path and name parts string path; string name; DiskFile::SplitFilename(filename, path, name); string::size_type where; // Trim ".par2" off of the end original name // Look for the last "." in the filename while (string::npos != (where = name.find_last_of('.'))) { // Trim what follows the last . string tail = name.substr(where+1); name = name.substr(0,where); // Was what followed the last "." "par2" if (0 == stricmp(tail.c_str(), "par2")) break; } // If what is left ends in ".volNNN-NNN" or ".volNNN+NNN" strip that as well // Is there another "." if (string::npos != (where = name.find_last_of('.'))) { // What follows the "." string tail = name.substr(where+1); // Scan what follows the last "." to see of it matches vol123-456 or vol123+456 int n = 0; string::const_iterator p; for (p=tail.begin(); p!=tail.end(); ++p) { char ch = *p; if (0 == n) { if (tolower(ch) == 'v') { n++; } else { break; } } else if (1 == n) { if (tolower(ch) == 'o') { n++; } else { break; } } else if (2 == n) { if (tolower(ch) == 'l') { n++; } else { break; } } else if (3 == n) { if (isdigit(ch)) {} else if (ch == '-' || ch == '+') { n++; } else { break; } } else if (4 == n) { if (isdigit(ch)) {} else { break; } } } // If we matched then retain only what preceeds the "." if (p == tail.end()) { name = name.substr(0,where); } } // Find files called "*.par2" or "name.*.par2" { string wildcard = name.empty() ? "*.par2" : name + ".*.par2"; list *files = DiskFile::FindFiles(path, wildcard); // Load packets from each file that was found for (list::const_iterator s=files->begin(); s!=files->end(); ++s) { LoadPacketsFromFile(*s); } delete files; } { string wildcard = name.empty() ? "*.PAR2" : name + ".*.PAR2"; list *files = DiskFile::FindFiles(path, wildcard); // Load packets from each file that was found for (list::const_iterator s=files->begin(); s!=files->end(); ++s) { LoadPacketsFromFile(*s); } delete files; } return true; } // Load packets from any other PAR2 files whose names are given on the command line bool Par2Repairer::LoadPacketsFromExtraFiles(const list &extrafiles) { for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { string filename = i->FileName(); // If the filename contains ".par2" anywhere if (string::npos != filename.find(".par2") || string::npos != filename.find(".PAR2")) { LoadPacketsFromFile(filename); } } return true; } // Check that the packets are consistent and discard any that are not bool Par2Repairer::CheckPacketConsistency(void) { // Do we have a main packet if (0 == mainpacket) { // If we don't have a main packet, then there is nothing more that we can do. // We cannot verify or repair any files. cerr << "Main packet not found." << endl; return false; } // Remember the block size from the main packet blocksize = mainpacket->BlockSize(); // Check that the recovery blocks have the correct amount of data // and discard any that don't { map::iterator rp = recoverypacketmap.begin(); while (rp != recoverypacketmap.end()) { if (rp->second->BlockSize() == blocksize) { ++rp; } else { cerr << "Incorrect sized recovery block for exponent " << rp->second->Exponent() << " discarded" << endl; delete rp->second; map::iterator x = rp++; recoverypacketmap.erase(x); } } } // Check for source files that have no description packet or where the // verification packet has the wrong number of entries and discard them. { map::iterator sf = sourcefilemap.begin(); while (sf != sourcefilemap.end()) { // Do we have a description packet DescriptionPacket *descriptionpacket = sf->second->GetDescriptionPacket(); if (descriptionpacket == 0) { // No description packet // Discard the source file delete sf->second; map::iterator x = sf++; sourcefilemap.erase(x); continue; } // Compute and store the block count from the filesize and blocksize sf->second->SetBlockCount(blocksize); // Do we have a verification packet VerificationPacket *verificationpacket = sf->second->GetVerificationPacket(); if (verificationpacket == 0) { // No verification packet // That is ok, but we won't be able to use block verification. // Proceed to the next file. ++sf; continue; } // Work out the block count for the file from the file size // and compare that with the verification packet u64 filesize = descriptionpacket->FileSize(); u32 blockcount = verificationpacket->BlockCount(); if ((filesize + blocksize-1) / blocksize != (u64)blockcount) { // The block counts are different! cerr << "Incorrectly sized verification packet for \"" << descriptionpacket->FileName() << "\" discarded" << endl; // Discard the source file delete sf->second; map::iterator x = sf++; sourcefilemap.erase(x); continue; } // Everything is ok. // Proceed to the next file ++sf; } } if (noiselevel > CommandLine::nlQuiet) { cout << "There are " << mainpacket->RecoverableFileCount() << " recoverable files and " << mainpacket->TotalFileCount() - mainpacket->RecoverableFileCount() << " other files." << endl; cout << "The block size used was " << blocksize << " bytes." << endl; } return true; } // Use the information in the main packet to get the source files // into the correct order and determine their filenames bool Par2Repairer::CreateSourceFileList(void) { // For each FileId entry in the main packet for (u32 filenumber=0; filenumberTotalFileCount(); filenumber++) { const MD5Hash &fileid = mainpacket->FileId(filenumber); // Look up the fileid in the source file map map::iterator sfmi = sourcefilemap.find(fileid); Par2RepairerSourceFile *sourcefile = (sfmi == sourcefilemap.end()) ? 0 :sfmi->second; if (sourcefile) { sourcefile->ComputeTargetFileName(searchpath); } sourcefiles.push_back(sourcefile); } return true; } // Determine the total number of DataBlocks for the recoverable source files // The allocate the DataBlocks and assign them to each source file bool Par2Repairer::AllocateSourceBlocks(void) { sourceblockcount = 0; u32 filenumber = 0; vector::iterator sf = sourcefiles.begin(); // For each recoverable source file while (filenumber < mainpacket->RecoverableFileCount() && sf != sourcefiles.end()) { // Do we have a source file Par2RepairerSourceFile *sourcefile = *sf; if (sourcefile) { sourceblockcount += sourcefile->BlockCount(); } else { // No details for this source file so we don't know what the // total number of source blocks is // sourceblockcount = 0; // break; } ++sf; ++filenumber; } // Did we determine the total number of source blocks if (sourceblockcount > 0) { // Yes. // Allocate all of the Source and Target DataBlocks (which will be used // to read and write data to disk). sourceblocks.resize(sourceblockcount); targetblocks.resize(sourceblockcount); // Which DataBlocks will be allocated first vector::iterator sourceblock = sourceblocks.begin(); vector::iterator targetblock = targetblocks.begin(); u64 totalsize = 0; u32 blocknumber = 0; filenumber = 0; sf = sourcefiles.begin(); while (filenumber < mainpacket->RecoverableFileCount() && sf != sourcefiles.end()) { Par2RepairerSourceFile *sourcefile = *sf; if (sourcefile) { totalsize += sourcefile->GetDescriptionPacket()->FileSize(); u32 blockcount = sourcefile->BlockCount(); // Allocate the source and target DataBlocks to the sourcefile sourcefile->SetBlocks(blocknumber, blockcount, sourceblock, targetblock, blocksize); blocknumber++; sourceblock += blockcount; targetblock += blockcount; } ++sf; ++filenumber; } blocksallocated = true; if (noiselevel > CommandLine::nlQuiet) { cout << "There are a total of " << sourceblockcount << " data blocks." << endl; cout << "The total size of the data files is " << totalsize << " bytes." << endl; } } return true; } // Create a verification hash table for all files for which we have not // found a complete version of the file and for which we have // a verification packet bool Par2Repairer::PrepareVerificationHashTable(void) { // Choose a size for the hash table verificationhashtable.SetLimit(sourceblockcount); // Will any files be block verifiable blockverifiable = false; // For each source file vector::iterator sf = sourcefiles.begin(); while (sf != sourcefiles.end()) { // Get the source file Par2RepairerSourceFile *sourcefile = *sf; if (sourcefile) { // Do we have a verification packet if (0 != sourcefile->GetVerificationPacket()) { // Yes. Load the verification entries into the hash table verificationhashtable.Load(sourcefile, blocksize); blockverifiable = true; } else { // No. We can only check the whole file unverifiablesourcefiles.push_back(sourcefile); } } ++sf; } return true; } // Compute the table for the sliding CRC computation bool Par2Repairer::ComputeWindowTable(void) { if (blockverifiable) { GenerateWindowTable(blocksize, windowtable); windowmask = ComputeWindowMask(blocksize); } return true; } static bool SortSourceFilesByFileName(Par2RepairerSourceFile *low, Par2RepairerSourceFile *high) { return low->TargetFileName() < high->TargetFileName(); } // Attempt to verify all of the source files bool Par2Repairer::VerifySourceFiles(void) { bool finalresult = true; // Created a sorted list of the source files and verify them in that // order rather than the order they are in the main packet. vector sortedfiles; u32 filenumber = 0; vector::iterator sf = sourcefiles.begin(); while (sf != sourcefiles.end()) { // Do we have a source file Par2RepairerSourceFile *sourcefile = *sf; if (sourcefile) { sortedfiles.push_back(sourcefile); } else { // Was this one of the recoverable files if (filenumber < mainpacket->RecoverableFileCount()) { cerr << "No details available for recoverable file number " << filenumber+1 << "." << endl << "Recovery will not be possible." << endl; // Set error but let verification of other files continue finalresult = false; } else { cerr << "No details available for non-recoverable file number " << filenumber - mainpacket->RecoverableFileCount() + 1 << endl; } } ++sf; } sort(sortedfiles.begin(), sortedfiles.end(), SortSourceFilesByFileName); // Start verifying the files sf = sortedfiles.begin(); while (sf != sortedfiles.end()) { // Do we have a source file Par2RepairerSourceFile *sourcefile = *sf; // What filename does the file use string filename = sourcefile->TargetFileName(); // Check to see if we have already used this file if (diskFileMap.Find(filename) != 0) { // The file has already been used! cerr << "Source file " << filenumber+1 << " is a duplicate." << endl; return false; } DiskFile *diskfile = new DiskFile; // Does the target file exist if (diskfile->Open(filename)) { // Yes. Record that fact. sourcefile->SetTargetExists(true); // Remember that the DiskFile is the target file sourcefile->SetTargetFile(diskfile); // Remember that we have processed this file bool success = diskFileMap.Insert(diskfile); assert(success); // Do the actual verification if (!VerifyDataFile(diskfile, sourcefile)) finalresult = false; // We have finished with the file for now diskfile->Close(); // Find out how much data we have found UpdateVerificationResults(); } else { // The file does not exist. delete diskfile; if (noiselevel > CommandLine::nlSilent) { string path; string name; DiskFile::SplitFilename(filename, path, name); cout << "Target: \"" << name << "\" - missing." << endl; } } ++sf; } return finalresult; } // Scan any extra files specified on the command line bool Par2Repairer::VerifyExtraFiles(const list &extrafiles) { for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end() && completefilecountRecoverableFileCount(); ++i) { string filename = i->FileName(); // If the filename does not include ".par2" we are interested in it. if (string::npos == filename.find(".par2") && string::npos == filename.find(".PAR2")) { filename = DiskFile::GetCanonicalPathname(filename); // Has this file already been dealt with if (diskFileMap.Find(filename) == 0) { DiskFile *diskfile = new DiskFile; // Does the file exist if (!diskfile->Open(filename)) { delete diskfile; continue; } // Remember that we have processed this file bool success = diskFileMap.Insert(diskfile); assert(success); // Do the actual verification VerifyDataFile(diskfile, 0); // Ignore errors // We have finished with the file for now diskfile->Close(); // Find out how much data we have found UpdateVerificationResults(); } } } return true; } // Attempt to match the data in the DiskFile with the source file bool Par2Repairer::VerifyDataFile(DiskFile *diskfile, Par2RepairerSourceFile *sourcefile) { MatchType matchtype; // What type of match was made MD5Hash hashfull; // The MD5 Hash of the whole file MD5Hash hash16k; // The MD5 Hash of the files 16k of the file // Are there any files that can be verified at the block level if (blockverifiable) { u32 count; // Scan the file at the block level. if (!ScanDataFile(diskfile, // [in] The file to scan sourcefile, // [in/out] Modified in the match is for another source file matchtype, // [out] hashfull, // [out] hash16k, // [out] count)) // [out] return false; switch (matchtype) { case eNoMatch: // No data was found at all. // Continue to next test. break; case ePartialMatch: { // We found some data. // Return them. return true; } break; case eFullMatch: { // We found a perfect match. sourcefile->SetCompleteFile(diskfile); // Return the match return true; } break; } } // We did not find a match for any blocks of data within the file, but if // there are any files for which we did not have a verification packet // we can try a simple match of the hash for the whole file. // Are there any files that cannot be verified at the block level if (unverifiablesourcefiles.size() > 0) { // Would we have already computed the file hashes if (!blockverifiable) { u64 filesize = diskfile->FileSize(); size_t buffersize = 1024*1024; if (buffersize > min(blocksize, filesize)) buffersize = (size_t)min(blocksize, filesize); char *buffer = new char[buffersize]; u64 offset = 0; MD5Context context; while (offset < filesize) { size_t want = (size_t)min((u64)buffersize, filesize-offset); if (!diskfile->Read(offset, buffer, want)) { delete [] buffer; return false; } // Will the newly read data reach the 16k boundary if (offset < 16384 && offset + want >= 16384) { context.Update(buffer, (size_t)(16384-offset)); // Compute the 16k hash MD5Context temp = context; temp.Final(hash16k); // Is there more data if (offset + want > 16384) { context.Update(&buffer[16384-offset], (size_t)(offset+want)-16384); } } else { context.Update(buffer, want); } offset += want; } // Compute the file hash MD5Hash hashfull; context.Final(hashfull); // If we did not have 16k of data, then the 16k hash // is the same as the full hash if (filesize < 16384) { hash16k = hashfull; } } list::iterator sf = unverifiablesourcefiles.begin(); // Compare the hash values of each source file for a match while (sf != unverifiablesourcefiles.end()) { sourcefile = *sf; // Does the file match if (sourcefile->GetCompleteFile() == 0 && diskfile->FileSize() == sourcefile->GetDescriptionPacket()->FileSize() && hash16k == sourcefile->GetDescriptionPacket()->Hash16k() && hashfull == sourcefile->GetDescriptionPacket()->HashFull()) { if (noiselevel > CommandLine::nlSilent) cout << diskfile->FileName() << " is a perfect match for " << sourcefile->GetDescriptionPacket()->FileName() << endl; // Record that we have a perfect match for this source file sourcefile->SetCompleteFile(diskfile); if (blocksallocated) { // Allocate all of the DataBlocks for the source file to the DiskFile u64 offset = 0; u64 filesize = sourcefile->GetDescriptionPacket()->FileSize(); vector::iterator sb = sourcefile->SourceBlocks(); while (offset < filesize) { DataBlock &datablock = *sb; datablock.SetLocation(diskfile, offset); datablock.SetLength(min(blocksize, filesize-offset)); offset += blocksize; ++sb; } } // Return the match return true; } ++sf; } } return true; } // Perform a sliding window scan of the DiskFile looking for blocks of data that // might belong to any of the source files (for which a verification packet was // available). If a block of data might be from more than one source file, prefer // the one specified by the "sourcefile" parameter. If the first data block // found is for a different source file then "sourcefile" is changed accordingly. bool Par2Repairer::ScanDataFile(DiskFile *diskfile, // [in] Par2RepairerSourceFile* &sourcefile, // [in/out] MatchType &matchtype, // [out] MD5Hash &hashfull, // [out] MD5Hash &hash16k, // [out] u32 &count) // [out] { // Remember which file we wanted to match Par2RepairerSourceFile *originalsourcefile = sourcefile; matchtype = eNoMatch; // Is the file empty if (diskfile->FileSize() == 0) { // If the file is empty, then just return return true; } string path; string name; DiskFile::SplitFilename(diskfile->FileName(), path, name); string shortname; if (name.size() > 56) { shortname = name.substr(0, 28) + "..." + name.substr(name.size()-28); } else { shortname = name; } // Create the checksummer for the file and start reading from it FileCheckSummer filechecksummer(diskfile, blocksize, windowtable, windowmask); if (!filechecksummer.Start()) return false; // Assume we will make a perfect match for the file matchtype = eFullMatch; // How many matches have we had count = 0; // How many blocks have already been found u32 duplicatecount = 0; // Have we found data blocks in this file that belong to more than one target file bool multipletargets = false; // Which block do we expect to find first const VerificationHashEntry *nextentry = 0; u64 progress = 0; // Whilst we have not reached the end of the file while (filechecksummer.Offset() < diskfile->FileSize()) { if (noiselevel > CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * progress / diskfile->FileSize()); u32 newfraction = (u32)(1000 * (progress = filechecksummer.Offset()) / diskfile->FileSize()); if (oldfraction != newfraction) { cout << "Scanning: \"" << shortname << "\": " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } // If we fail to find a match, it might be because it was a duplicate of a block // that we have already found. bool duplicate; // Look for a match const VerificationHashEntry *currententry = verificationhashtable.FindMatch(nextentry, sourcefile, filechecksummer, duplicate); // Did we find a match if (currententry != 0) { // Is this the first match if (count == 0) { // Which source file was it sourcefile = currententry->SourceFile(); // If the first match found was not actually the first block // for the source file, or it was not at the start of the // data file: then this is a partial match. if (!currententry->FirstBlock() || filechecksummer.Offset() != 0) { matchtype = ePartialMatch; } } else { // If the match found is not the one which was expected // then this is a partial match if (currententry != nextentry) { matchtype = ePartialMatch; } // Is the match from a different source file if (sourcefile != currententry->SourceFile()) { multipletargets = true; } } if (blocksallocated) { // Record the match currententry->SetBlock(diskfile, filechecksummer.Offset()); } // Update the number of matches found count++; // What entry do we expect next nextentry = currententry->Next(); // Advance to the next block if (!filechecksummer.Jump(currententry->GetDataBlock()->GetLength())) return false; } else { // This cannot be a perfect match matchtype = ePartialMatch; // Was this a duplicate match if (duplicate) { duplicatecount++; // What entry would we expect next nextentry = 0; // Advance one whole block if (!filechecksummer.Jump(blocksize)) return false; } else { // What entry do we expect next nextentry = 0; // Advance 1 byte if (!filechecksummer.Step()) return false; } } } // Get the Full and 16k hash values of the file filechecksummer.GetFileHashes(hashfull, hash16k); // Did we make any matches at all if (count > 0) { // If this still might be a perfect match, check the // hashes, file size, and number of blocks to confirm. if (matchtype != eFullMatch || count != sourcefile->GetVerificationPacket()->BlockCount() || diskfile->FileSize() != sourcefile->GetDescriptionPacket()->FileSize() || hashfull != sourcefile->GetDescriptionPacket()->HashFull() || hash16k != sourcefile->GetDescriptionPacket()->Hash16k()) { matchtype = ePartialMatch; if (noiselevel > CommandLine::nlSilent) { // Did we find data from multiple target files if (multipletargets) { // Were we scanning the target file or an extra file if (originalsourcefile != 0) { cout << "Target: \"" << name << "\" - damaged, found " << count << " data blocks from several target files." << endl; } else { cout << "File: \"" << name << "\" - found " << count << " data blocks from several target files." << endl; } } else { // Did we find data blocks that belong to the target file if (originalsourcefile == sourcefile) { cout << "Target: \"" << name << "\" - damaged. Found " << count << " of " << sourcefile->GetVerificationPacket()->BlockCount() << " data blocks." << endl; } // Were we scanning the target file or an extra file else if (originalsourcefile != 0) { string targetname; DiskFile::SplitFilename(sourcefile->TargetFileName(), path, targetname); cout << "Target: \"" << name << "\" - damaged. Found " << count << " of " << sourcefile->GetVerificationPacket()->BlockCount() << " data blocks from \"" << targetname << "\"." << endl; } else { string targetname; DiskFile::SplitFilename(sourcefile->TargetFileName(), path, targetname); cout << "File: \"" << name << "\" - found " << count << " of " << sourcefile->GetVerificationPacket()->BlockCount() << " data blocks from \"" << targetname << "\"." << endl; } } } } else { if (noiselevel > CommandLine::nlSilent) { // Did we match the target file if (originalsourcefile == sourcefile) { cout << "Target: \"" << name << "\" - found." << endl; } // Were we scanning the target file or an extra file else if (originalsourcefile != 0) { string targetname; DiskFile::SplitFilename(sourcefile->TargetFileName(), path, targetname); cout << "Target: \"" << name << "\" - is a match for \"" << targetname << "\"." << endl; } else { string targetname; DiskFile::SplitFilename(sourcefile->TargetFileName(), path, targetname); cout << "File: \"" << name << "\" - is a match for \"" << targetname << "\"." << endl; } } } } else { matchtype = eNoMatch; if (noiselevel > CommandLine::nlSilent) { // We found not data, but did the file actually contain blocks we // had already found in other files. if (duplicatecount > 0) { cout << "File: \"" << name << "\" - found " << duplicatecount << " duplicate data blocks." << endl; } else { cout << "File: \"" << name << "\" - no data found." << endl; } } } return true; } // Find out how much data we have found void Par2Repairer::UpdateVerificationResults(void) { availableblockcount = 0; missingblockcount = 0; completefilecount = 0; renamedfilecount = 0; damagedfilecount = 0; missingfilecount = 0; u32 filenumber = 0; vector::iterator sf = sourcefiles.begin(); // Check the recoverable files while (sf != sourcefiles.end() && filenumber < mainpacket->TotalFileCount()) { Par2RepairerSourceFile *sourcefile = *sf; if (sourcefile) { // Was a perfect match for the file found if (sourcefile->GetCompleteFile() != 0) { // Is it the target file or a different one if (sourcefile->GetCompleteFile() == sourcefile->GetTargetFile()) { completefilecount++; } else { renamedfilecount++; } availableblockcount += sourcefile->BlockCount(); } else { // Count the number of blocks that have been found vector::iterator sb = sourcefile->SourceBlocks(); for (u32 blocknumber=0; blocknumberBlockCount(); ++blocknumber, ++sb) { DataBlock &datablock = *sb; if (datablock.IsSet()) availableblockcount++; } // Does the target file exist if (sourcefile->GetTargetExists()) { damagedfilecount++; } else { missingfilecount++; } } } else { missingfilecount++; } ++filenumber; ++sf; } missingblockcount = sourceblockcount - availableblockcount; } // Check the verification results and report the results bool Par2Repairer::CheckVerificationResults(void) { // Is repair needed if (completefilecount < mainpacket->RecoverableFileCount() || renamedfilecount > 0 || damagedfilecount > 0 || missingfilecount > 0) { if (noiselevel > CommandLine::nlSilent) cout << "Repair is required." << endl; if (noiselevel > CommandLine::nlQuiet) { if (renamedfilecount > 0) cout << renamedfilecount << " file(s) have the wrong name." << endl; if (missingfilecount > 0) cout << missingfilecount << " file(s) are missing." << endl; if (damagedfilecount > 0) cout << damagedfilecount << " file(s) exist but are damaged." << endl; if (completefilecount > 0) cout << completefilecount << " file(s) are ok." << endl; cout << "You have " << availableblockcount << " out of " << sourceblockcount << " data blocks available." << endl; if (recoverypacketmap.size() > 0) cout << "You have " << (u32)recoverypacketmap.size() << " recovery blocks available." << endl; } // Is repair possible if (recoverypacketmap.size() >= missingblockcount) { if (noiselevel > CommandLine::nlSilent) cout << "Repair is possible." << endl; if (noiselevel > CommandLine::nlQuiet) { if (recoverypacketmap.size() > missingblockcount) cout << "You have an excess of " << (u32)recoverypacketmap.size() - missingblockcount << " recovery blocks." << endl; if (missingblockcount > 0) cout << missingblockcount << " recovery blocks will be used to repair." << endl; else if (recoverypacketmap.size()) cout << "None of the recovery blocks will be used for the repair." << endl; } return true; } else { if (noiselevel > CommandLine::nlSilent) { cout << "Repair is not possible." << endl; cout << "You need " << missingblockcount - recoverypacketmap.size() << " more recovery blocks to be able to repair." << endl; } return false; } } else { if (noiselevel > CommandLine::nlSilent) cout << "All files are correct, repair is not required." << endl; return true; } return true; } // Rename any damaged or missnamed target files. bool Par2Repairer::RenameTargetFiles(void) { u32 filenumber = 0; vector::iterator sf = sourcefiles.begin(); // Rename any damaged target files while (sf != sourcefiles.end() && filenumber < mainpacket->TotalFileCount()) { Par2RepairerSourceFile *sourcefile = *sf; // If the target file exists but is not a complete version of the file if (sourcefile->GetTargetExists() && sourcefile->GetTargetFile() != sourcefile->GetCompleteFile()) { DiskFile *targetfile = sourcefile->GetTargetFile(); // Rename it diskFileMap.Remove(targetfile); if (!targetfile->Rename()) return false; bool success = diskFileMap.Insert(targetfile); assert(success); // We no longer have a target file sourcefile->SetTargetExists(false); sourcefile->SetTargetFile(0); } ++sf; ++filenumber; } filenumber = 0; sf = sourcefiles.begin(); // Rename any missnamed but complete versions of the files while (sf != sourcefiles.end() && filenumber < mainpacket->TotalFileCount()) { Par2RepairerSourceFile *sourcefile = *sf; // If there is no targetfile and there is a complete version if (sourcefile->GetTargetFile() == 0 && sourcefile->GetCompleteFile() != 0) { DiskFile *targetfile = sourcefile->GetCompleteFile(); // Rename it diskFileMap.Remove(targetfile); if (!targetfile->Rename(sourcefile->TargetFileName())) return false; bool success = diskFileMap.Insert(targetfile); assert(success); // This file is now the target file sourcefile->SetTargetExists(true); sourcefile->SetTargetFile(targetfile); // We have one more complete file completefilecount++; } ++sf; ++filenumber; } return true; } // Work out which files are being repaired, create them, and allocate // target DataBlocks to them, and remember them for later verification. bool Par2Repairer::CreateTargetFiles(void) { u32 filenumber = 0; vector::iterator sf = sourcefiles.begin(); // Create any missing target files while (sf != sourcefiles.end() && filenumber < mainpacket->TotalFileCount()) { Par2RepairerSourceFile *sourcefile = *sf; // If the file does not exist if (!sourcefile->GetTargetExists()) { DiskFile *targetfile = new DiskFile; string filename = sourcefile->TargetFileName(); u64 filesize = sourcefile->GetDescriptionPacket()->FileSize(); // Create the target file if (!targetfile->Create(filename, filesize)) { delete targetfile; return false; } // This file is now the target file sourcefile->SetTargetExists(true); sourcefile->SetTargetFile(targetfile); // Remember this file bool success = diskFileMap.Insert(targetfile); assert(success); u64 offset = 0; vector::iterator tb = sourcefile->TargetBlocks(); // Allocate all of the target data blocks while (offset < filesize) { DataBlock &datablock = *tb; datablock.SetLocation(targetfile, offset); datablock.SetLength(min(blocksize, filesize-offset)); offset += blocksize; ++tb; } // Add the file to the list of those that will need to be verified // once the repair has completed. verifylist.push_back(sourcefile); } ++sf; ++filenumber; } return true; } // Work out which data blocks are available, which need to be copied // directly to the output, and which need to be recreated, and compute // the appropriate Reed Solomon matrix. bool Par2Repairer::ComputeRSmatrix(void) { inputblocks.resize(sourceblockcount); // The DataBlocks that will read from disk copyblocks.resize(availableblockcount); // Those DataBlocks which need to be copied outputblocks.resize(missingblockcount); // Those DataBlocks that will re recalculated vector::iterator inputblock = inputblocks.begin(); vector::iterator copyblock = copyblocks.begin(); vector::iterator outputblock = outputblocks.begin(); // Build an array listing which source data blocks are present and which are missing vector present; present.resize(sourceblockcount); vector::iterator sourceblock = sourceblocks.begin(); vector::iterator targetblock = targetblocks.begin(); vector::iterator pres = present.begin(); // Iterate through all source blocks for all files while (sourceblock != sourceblocks.end()) { // Was this block found if (sourceblock->IsSet()) { // // Open the file the block was found in. // if (!sourceblock->Open()) // return false; // Record that the block was found *pres = true; // Add the block to the list of those which will be read // as input (and which might also need to be copied). *inputblock = &*sourceblock; *copyblock = &*targetblock; ++inputblock; ++copyblock; } else { // Record that the block was missing *pres = false; // Add the block to the list of those to be written *outputblock = &*targetblock; ++outputblock; } ++sourceblock; ++targetblock; ++pres; } // Set the number of source blocks and which of them are present if (!rs.SetInput(present)) return false; // Start iterating through the available recovery packets map::iterator rp = recoverypacketmap.begin(); // Continue to fill the remaining list of data blocks to be read while (inputblock != inputblocks.end()) { // Get the next available recovery packet u32 exponent = rp->first; RecoveryPacket* recoverypacket = rp->second; // Get the DataBlock from the recovery packet DataBlock *recoveryblock = recoverypacket->GetDataBlock(); // // Make sure the file is open // if (!recoveryblock->Open()) // return false; // Add the recovery block to the list of blocks that will be read *inputblock = recoveryblock; // Record that the corresponding exponent value is the next one // to use in the RS matrix if (!rs.SetOutput(true, (u16)exponent)) return false; ++inputblock; ++rp; } // If we need to, compute and solve the RS matrix if (missingblockcount == 0) return true; bool success = rs.Compute(noiselevel); return success; } // Allocate memory buffers for reading and writing data to disk. bool Par2Repairer::AllocateBuffers(size_t memorylimit) { // Would single pass processing use too much memory if (blocksize * missingblockcount > memorylimit) { // Pick a size that is small enough chunksize = ~3 & (memorylimit / missingblockcount); } else { chunksize = (size_t)blocksize; } // Allocate the two buffers inputbuffer = new u8[(size_t)chunksize]; outputbuffer = new u8[(size_t)chunksize * missingblockcount]; if (inputbuffer == NULL || outputbuffer == NULL) { cerr << "Could not allocate buffer memory." << endl; return false; } return true; } // Read source data, process it through the RS matrix and write it to disk. bool Par2Repairer::ProcessData(u64 blockoffset, size_t blocklength) { u64 totalwritten = 0; // Clear the output buffer memset(outputbuffer, 0, (size_t)chunksize * missingblockcount); vector::iterator inputblock = inputblocks.begin(); vector::iterator copyblock = copyblocks.begin(); u32 inputindex = 0; DiskFile *lastopenfile = NULL; // Are there any blocks which need to be reconstructed if (missingblockcount > 0) { // For each input block while (inputblock != inputblocks.end()) { // Are we reading from a new file? if (lastopenfile != (*inputblock)->GetDiskFile()) { // Close the last file if (lastopenfile != NULL) { lastopenfile->Close(); } // Open the new file lastopenfile = (*inputblock)->GetDiskFile(); if (!lastopenfile->Open()) { return false; } } // Read data from the current input block if (!(*inputblock)->ReadData(blockoffset, blocklength, inputbuffer)) return false; // Have we reached the last source data block if (copyblock != copyblocks.end()) { // Does this block need to be copied to the target file if ((*copyblock)->IsSet()) { size_t wrote; // Write the block back to disk in the new target file if (!(*copyblock)->WriteData(blockoffset, blocklength, inputbuffer, wrote)) return false; totalwritten += wrote; } ++copyblock; } // For each output block for (u32 outputindex=0; outputindex CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * progress / totaldata); progress += blocklength; u32 newfraction = (u32)(1000 * progress / totaldata); if (oldfraction != newfraction) { cout << "Repairing: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } } ++inputblock; ++inputindex; } } else { // Reconstruction is not required, we are just copying blocks between files // For each block that might need to be copied while (copyblock != copyblocks.end()) { // Does this block need to be copied if ((*copyblock)->IsSet()) { // Are we reading from a new file? if (lastopenfile != (*inputblock)->GetDiskFile()) { // Close the last file if (lastopenfile != NULL) { lastopenfile->Close(); } // Open the new file lastopenfile = (*inputblock)->GetDiskFile(); if (!lastopenfile->Open()) { return false; } } // Read data from the current input block if (!(*inputblock)->ReadData(blockoffset, blocklength, inputbuffer)) return false; size_t wrote; if (!(*copyblock)->WriteData(blockoffset, blocklength, inputbuffer, wrote)) return false; totalwritten += wrote; } if (noiselevel > CommandLine::nlQuiet) { // Update a progress indicator u32 oldfraction = (u32)(1000 * progress / totaldata); progress += blocklength; u32 newfraction = (u32)(1000 * progress / totaldata); if (oldfraction != newfraction) { cout << "Processing: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush; } } ++copyblock; ++inputblock; } } // Close the last file if (lastopenfile != NULL) { lastopenfile->Close(); } if (noiselevel > CommandLine::nlQuiet) cout << "Writing recovered data\r"; // For each output block that has been recomputed vector::iterator outputblock = outputblocks.begin(); for (u32 outputindex=0; outputindexWriteData(blockoffset, blocklength, outbuf, wrote)) return false; totalwritten += wrote; ++outputblock; } if (noiselevel > CommandLine::nlQuiet) cout << "Wrote " << totalwritten << " bytes to disk" << endl; return true; } // Verify that all of the reconstructed target files are now correct bool Par2Repairer::VerifyTargetFiles(void) { bool finalresult = true; // Verify the target files in alphabetical order sort(verifylist.begin(), verifylist.end(), SortSourceFilesByFileName); // Iterate through each file in the verification list for (vector::iterator sf = verifylist.begin(); sf != verifylist.end(); ++sf) { Par2RepairerSourceFile *sourcefile = *sf; DiskFile *targetfile = sourcefile->GetTargetFile(); // Close the file if (targetfile->IsOpen()) targetfile->Close(); // Mark all data blocks for the file as unknown vector::iterator sb = sourcefile->SourceBlocks(); for (u32 blocknumber=0; blocknumberBlockCount(); blocknumber++) { sb->ClearLocation(); ++sb; } // Say we don't have a complete version of the file sourcefile->SetCompleteFile(0); // Re-open the target file if (!targetfile->Open()) { finalresult = false; continue; } // Verify the file again if (!VerifyDataFile(targetfile, sourcefile)) finalresult = false; // Close the file again targetfile->Close(); // Find out how much data we have found UpdateVerificationResults(); } return finalresult; } // Delete all of the partly reconstructed files bool Par2Repairer::DeleteIncompleteTargetFiles(void) { vector::iterator sf = verifylist.begin(); // Iterate through each file in the verification list while (sf != verifylist.end()) { Par2RepairerSourceFile *sourcefile = *sf; if (sourcefile->GetTargetExists()) { DiskFile *targetfile = sourcefile->GetTargetFile(); // Close and delete the file if (targetfile->IsOpen()) targetfile->Close(); targetfile->Delete(); // Forget the file diskFileMap.Remove(targetfile); delete targetfile; // There is no target file sourcefile->SetTargetExists(false); sourcefile->SetTargetFile(0); } ++sf; } return true; } par2cmdline-0.4/par2repairer.h0000644000000000000000000002104210037470226011753 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR2REPAIRER_H__ #define __PAR2REPAIRER_H__ class Par2Repairer { public: Par2Repairer(void); ~Par2Repairer(void); Result Process(const CommandLine &commandline, bool dorepair); protected: // Steps in verifying and repairing files: // Load packets from the specified file bool LoadPacketsFromFile(string filename); // Finish loading a recovery packet bool LoadRecoveryPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Finish loading a file description packet bool LoadDescriptionPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Finish loading a file verification packet bool LoadVerificationPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Finish loading the main packet bool LoadMainPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Finish loading the creator packet bool LoadCreatorPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Load packets from other PAR2 files with names based on the original PAR2 file bool LoadPacketsFromOtherFiles(string filename); // Load packets from any other PAR2 files whose names are given on the command line bool LoadPacketsFromExtraFiles(const list &extrafiles); // Check that the packets are consistent and discard any that are not bool CheckPacketConsistency(void); // Use the information in the main packet to get the source files // into the correct order and determine their filenames bool CreateSourceFileList(void); // Determine the total number of DataBlocks for the recoverable source files // The allocate the DataBlocks and assign them to each source file bool AllocateSourceBlocks(void); // Create a verification hash table for all files for which we have not // found a complete version of the file and for which we have // a verification packet bool PrepareVerificationHashTable(void); // Compute the table for the sliding CRC computation bool ComputeWindowTable(void); // Attempt to verify all of the source files bool VerifySourceFiles(void); // Scan any extra files specified on the command line bool VerifyExtraFiles(const list &extrafiles); // Attempt to match the data in the DiskFile with the source file bool VerifyDataFile(DiskFile *diskfile, Par2RepairerSourceFile *sourcefile); // Perform a sliding window scan of the DiskFile looking for blocks of data that // might belong to any of the source files (for which a verification packet was // available). If a block of data might be from more than one source file, prefer // the one specified by the "sourcefile" parameter. If the first data block // found is for a different source file then "sourcefile" is changed accordingly. bool ScanDataFile(DiskFile *diskfile, // [in] The file being scanned Par2RepairerSourceFile* &sourcefile, // [in/out] The source file matched MatchType &matchtype, // [out] The type of match MD5Hash &hashfull, // [out] The full hash of the file MD5Hash &hash16k, // [out] The hash of the first 16k u32 &count); // [out] The number of blocks found // Find out how much data we have found void UpdateVerificationResults(void); // Check the verification results and report the results bool CheckVerificationResults(void); // Rename any damaged or missnamed target files. bool RenameTargetFiles(void); // Work out which files are being repaired, create them, and allocate // target DataBlocks to them, and remember them for later verification. bool CreateTargetFiles(void); // Work out which data blocks are available, which need to be copied // directly to the output, and which need to be recreated, and compute // the appropriate Reed Solomon matrix. bool ComputeRSmatrix(void); // Allocate memory buffers for reading and writing data to disk. bool AllocateBuffers(size_t memorylimit); // Read source data, process it through the RS matrix and write it to disk. bool ProcessData(u64 blockoffset, size_t blocklength); // Verify that all of the reconstructed target files are now correct bool VerifyTargetFiles(void); // Delete all of the partly reconstructed files bool DeleteIncompleteTargetFiles(void); protected: CommandLine::NoiseLevel noiselevel; // OnScreen display string searchpath; // Where to find files on disk bool firstpacket; // Whether or not a valid packet has been found. MD5Hash setid; // The SetId extracted from the first packet. map recoverypacketmap; // One recovery packet for each exponent value. MainPacket *mainpacket; // One copy of the main packet. CreatorPacket *creatorpacket; // One copy of the creator packet. DiskFileMap diskFileMap; map sourcefilemap;// Map from FileId to SourceFile vector sourcefiles; // The source files vector verifylist; // Those source files that are being repaired u64 blocksize; // The block size. u64 chunksize; // How much of a block can be processed. u32 sourceblockcount; // The total number of blocks u32 availableblockcount; // How many undamaged blocks have been found u32 missingblockcount; // How many blocks are missing bool blocksallocated; // Whether or not the DataBlocks have been allocated vector sourceblocks; // The DataBlocks that will be read from disk vector targetblocks; // The DataBlocks that will be written to disk u32 windowtable[256]; // Table for sliding CRCs u32 windowmask; // Maks for sliding CRCs bool blockverifiable; // Whether and files can be verified at the block level VerificationHashTable verificationhashtable; // Hash table for block verification list unverifiablesourcefiles; // Files that are not block verifiable u32 completefilecount; // How many files are fully verified u32 renamedfilecount; // How many files are verified but have the wrong name u32 damagedfilecount; // How many files exist but are damaged u32 missingfilecount; // How many files are completely missing vector inputblocks; // Which DataBlocks will be read from disk vector copyblocks; // Which DataBlocks will copied back to disk vector outputblocks; // Which DataBlocks have to calculated using RS ReedSolomon rs; // The Reed Solomon matrix. void *inputbuffer; // Buffer for reading DataBlocks (chunksize) void *outputbuffer; // Buffer for writing DataBlocks (chunksize * missingblockcount) u64 progress; // How much data has been processed. u64 totaldata; // Total amount of data to be processed. }; #endif // __PAR2REPAIRER_H__ par2cmdline-0.4/par2repairersourcefile.cpp0000755000000000000000000001032307716445034014403 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif Par2RepairerSourceFile::Par2RepairerSourceFile(DescriptionPacket *_descriptionpacket, VerificationPacket *_verificationpacket) { firstblocknumber = 0; descriptionpacket = _descriptionpacket; verificationpacket = _verificationpacket; // verificationhashtable = 0; targetexists = false; targetfile = 0; completefile = 0; } Par2RepairerSourceFile::~Par2RepairerSourceFile(void) { delete descriptionpacket; delete verificationpacket; // delete verificationhashtable; } void Par2RepairerSourceFile::SetDescriptionPacket(DescriptionPacket *_descriptionpacket) { descriptionpacket = _descriptionpacket; } void Par2RepairerSourceFile::SetVerificationPacket(VerificationPacket *_verificationpacket) { verificationpacket = _verificationpacket; } void Par2RepairerSourceFile::ComputeTargetFileName(string path) { // Get a version of the filename compatible with the OS string filename = DiskFile::TranslateFilename(descriptionpacket->FileName()); // Strip the path from the filename string::size_type where; if (string::npos != (where = filename.find_last_of('\\')) || string::npos != (where = filename.find_last_of('/')) #ifdef WIN32 || string::npos != (where = filename.find_last_of(':')) #endif ) { filename = filename.substr(where+1); } targetfilename = path + filename; } string Par2RepairerSourceFile::TargetFileName(void) const { return targetfilename; } void Par2RepairerSourceFile::SetTargetFile(DiskFile *diskfile) { targetfile = diskfile; } DiskFile* Par2RepairerSourceFile::GetTargetFile(void) const { return targetfile; } void Par2RepairerSourceFile::SetTargetExists(bool exists) { targetexists = exists; } bool Par2RepairerSourceFile::GetTargetExists(void) const { return targetexists; } void Par2RepairerSourceFile::SetCompleteFile(DiskFile *diskfile) { completefile = diskfile; } DiskFile* Par2RepairerSourceFile::GetCompleteFile(void) const { return completefile; } // Remember which source and target blocks will be used by this file // and set their lengths appropriately void Par2RepairerSourceFile::SetBlocks(u32 _blocknumber, u32 _blockcount, vector::iterator _sourceblocks, vector::iterator _targetblocks, u64 blocksize) { firstblocknumber = _blocknumber; blockcount = _blockcount; sourceblocks = _sourceblocks; targetblocks = _targetblocks; if (blockcount > 0) { u64 filesize = descriptionpacket->FileSize(); vector::iterator sb = sourceblocks; for (u32 blocknumber=0; blocknumberFileSize() + blocksize-1) / blocksize); } else { blockcount = 0; } } par2cmdline-0.4/par2repairersourcefile.h0000755000000000000000000001043607711442272014051 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __PAR2REPAIRERSOURCEFILE_H__ #define __PAR2REPAIRERSOURCEFILE_H__ enum MatchType { eNoMatch = 0, ePartialMatch, eFullMatch }; // The Par2RepairerSourceFile object is used during verification and repair // to record details about a particular source file and the data blocks // for that file. class Par2RepairerSourceFile { public: // Construct the object and set the description and verification packets Par2RepairerSourceFile(DescriptionPacket *descriptionpacket, VerificationPacket *verificationpacket); ~Par2RepairerSourceFile(void); // Get/Set the description packet DescriptionPacket* GetDescriptionPacket(void) const {return descriptionpacket;} void SetDescriptionPacket(DescriptionPacket *descriptionpacket); // Get/Set the verification packet VerificationPacket* GetVerificationPacket(void) const {return verificationpacket;} void SetVerificationPacket(VerificationPacket *verificationpacket); // Record the details as to which data blocks belong to this source // file and set the length of each allocated block correctly. void SetBlocks(u32 _blocknumber, u32 _blockcount, vector::iterator _sourceblocks, vector::iterator _targetblocks, u64 blocksize); // Determine the block count from the file size and block size. void SetBlockCount(u64 blocksize); // Set/Get which DiskFile will contain the final repaired version of the file void SetTargetFile(DiskFile *diskfile); DiskFile* GetTargetFile(void) const; // Set/Get whether or not the target file actually exists void SetTargetExists(bool exists); bool GetTargetExists(void) const; // Set/Get which DiskFile contains a full undamaged version of the source file void SetCompleteFile(DiskFile *diskfile); DiskFile* GetCompleteFile(void) const; // Compute/Get the filename for the final repaired version of the file void ComputeTargetFileName(string path); string TargetFileName(void) const; // Get the number of blocks that the file uses u32 BlockCount(void) const {return blockcount;} // Get the relative block number of the first block in the file u32 FirstBlockNumber(void) const {return firstblocknumber;} // Get the first source DataBlock for the file vector::iterator SourceBlocks(void) const {return sourceblocks;} // Get the first target DataBlock for the file vector::iterator TargetBlocks(void) const {return targetblocks;} protected: DescriptionPacket *descriptionpacket; // The file description packet VerificationPacket *verificationpacket; // The file verification packet u32 blockcount; // The number of DataBlocks in the file u32 firstblocknumber; // The block number of the first DataBlock vector::iterator sourceblocks; // The first source DataBlock vector::iterator targetblocks; // The first target DataBlock bool targetexists; // Whether the target file exists DiskFile *targetfile; // The final version of the file DiskFile *completefile; // A complete version of the file string targetfilename; // The filename of the target file }; #endif // __PAR2REPAIRERSOURCEFILE_H__ par2cmdline-0.4/recoverypacket.cpp0000644000000000000000000001006107664453172012752 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif RecoveryPacket::RecoveryPacket(void) { diskfile = NULL; offset = 0; packetcontext = NULL; } RecoveryPacket::~RecoveryPacket(void) { delete packetcontext; } // Create a recovery packet. // The packet header can be almost completely filled in using the supplied // information and computation of the hash of the packet started immediately. // The hash will be updated as new data is written to the packet. void RecoveryPacket::Create(DiskFile *_diskfile, u64 _offset, u64 _blocksize, u32 _exponent, const MD5Hash &_setid) { diskfile = _diskfile; offset = _offset; // Record everything we know in the packet. packet.header.magic = packet_magic; packet.header.length = sizeof(packet) + _blocksize; //packet.header.hash; // Not known yet. packet.header.setid = _setid; packet.header.type = recoveryblockpacket_type; packet.exponent = _exponent; // Start computation of the packet hash packetcontext = new MD5Context; packetcontext->Update(&packet.header.setid, sizeof(RECOVERYBLOCKPACKET)-offsetof(RECOVERYBLOCKPACKET, header.setid)); // Set the data block to immediatly follow the header on disk datablock.SetLocation(_diskfile, _offset + sizeof(packet)); datablock.SetLength(_blocksize); } // Write data from the buffer to the data block on disk bool RecoveryPacket::WriteData(u64 position, size_t size, const void *buffer) { // Update the packet hash packetcontext->Update(buffer, size); // Write the data to the data block size_t wrote; return datablock.WriteData(position, size, buffer, wrote); } // Write the header of the packet to disk bool RecoveryPacket::WriteHeader(void) { // Finish computing the packet hash packetcontext->Final(packet.header.hash); // Write the header to disk return diskfile->Write(offset, &packet, sizeof(packet)); } // Load the recovery packet from disk. // // The header of the packet will already have been read from disk. The only // thing that actually needs to be read is the exponent value. // The recovery data is not read from disk at this point. Its location // is recovered in the DataBlock object. bool RecoveryPacket::Load(DiskFile *_diskfile, u64 _offset, PACKET_HEADER &_header) { diskfile = _diskfile; offset = _offset; // Is the packet actually large enough if (_header.length <= sizeof(packet)) { return false; } // Save the fixed header packet.header = _header; // Set the data block to immediatly follow the header on disk datablock.SetLocation(diskfile, offset + sizeof(packet)); datablock.SetLength(packet.header.length - sizeof(packet)); // Read the rest of the packet header return diskfile->Read(offset + sizeof(packet.header), &packet.exponent, sizeof(packet)-sizeof(packet.header)); } par2cmdline-0.4/recoverypacket.h0000644000000000000000000000676607664453172012440 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __RECOVERYPACKET_H__ #define __RECOVERYPACKET_H__ // The RecoveryPacket object is used to access a specific recovery // packet within a recovery file (for when creating them, or using // them during a repair operation). // Because the actual recovery data for the packet may be large, the // RecoveryPacket object only contains a copy of packet header and // exponent value for the block and uses a DataBlock object for // all accesses to the actual recovery data in the packet. class RecoveryPacket { public: RecoveryPacket(void); ~RecoveryPacket(void); public: // Create a recovery packet for a specified file. void Create(DiskFile *diskfile, // Which file will the packet be stored in u64 offset, // At what offset will the packet be stored u64 blocksize, // How much recovery data will it contain u32 exponent, // What exponent value will be used const MD5Hash &setid); // What is the SetId // Write some data to the recovery data block and update the recovery packet. bool WriteData(u64 position, // Relative position within the data block size_t size, // Size of data to write to block const void *buffer); // Buffer containing the data to write // Finish computing the hash of the recovery packet and write the header to disk. bool WriteHeader(void); public: // Load a recovery packet from a specified file bool Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); public: // Get the lenght of the packet. u64 PacketLength(void) const; // The the exponent of the packet. u32 Exponent(void) const; // The length of the recovery data u64 BlockSize(void) const; // The data block DataBlock* GetDataBlock(void); protected: DiskFile *diskfile; // The specific file that this packet is stored in u64 offset; // The offset at which the packet is stored RECOVERYBLOCKPACKET packet; // The packet (excluding the actual recovery data) MD5Context *packetcontext; // MD5 Context used to compute the packet hash DataBlock datablock; // The recovery data block. }; inline u64 RecoveryPacket::PacketLength(void) const { return packet.header.length; } inline u32 RecoveryPacket::Exponent(void) const { return packet.exponent; } inline u64 RecoveryPacket::BlockSize(void) const { return packet.header.length - sizeof(packet); } inline DataBlock* RecoveryPacket::GetDataBlock(void) { return &datablock; } #endif // __RECOVERYPACKET_H__ par2cmdline-0.4/reedsolomon.cpp0000644000000000000000000002172207664453173012261 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif u32 gcd(u32 a, u32 b) { if (a && b) { while (a && b) { if (a>b) { a = a%b; } else { b = b%a; } } return a+b; } else { return 0; } } bool ReedSolomon::SetInput(const vector &present) { inputcount = (u32)present.size(); datapresentindex = new u32[inputcount]; datamissingindex = new u32[inputcount]; database = new G::ValueType[inputcount]; G::ValueType base = 1; for (unsigned int index=0; index::SetInput(u32 count) { inputcount = count; datapresentindex = new u32[inputcount]; datamissingindex = new u32[inputcount]; database = new G::ValueType[inputcount]; G::ValueType base = 1; for (unsigned int index=0; index::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer) { // Look up the appropriate element in the RS matrix Galois8 factor = leftmatrix[outputindex * (datapresent + datamissing) + inputindex]; // Do nothing if the factor happens to be 0 if (factor == 0) return eSuccess; #ifdef LONGMULTIPLY // The 8-bit long multiplication tables Galois8 *table = glmt->tables; // Split the factor into Low and High bytes unsigned int fl = (factor >> 0) & 0xff; // Get the four separate multiplication tables Galois8 *LL = &table[(0*256 + fl) * 256 + 0]; // factor.low * source.low // Combine the four multiplication tables into two unsigned int L[256]; unsigned int *pL = &L[0]; for (unsigned int i=0; i<256; i++) { *pL = *LL; pL++; LL++; } // Treat the buffers as arrays of 32-bit unsigned ints. u32 *src4 = (u32 *)inputbuffer; u32 *end4 = (u32 *)&((u8*)inputbuffer)[size & ~3]; u32 *dst4 = (u32 *)outputbuffer; // Process the data while (src4 < end4) { u32 s = *src4++; // Use the two lookup tables computed earlier *dst4++ ^= (L[(s >> 0) & 0xff] ) ^ (L[(s >> 8) & 0xff] << 8 ) ^ (L[(s >> 16)& 0xff] << 16) ^ (L[(s >> 24)& 0xff] << 24); } // Process any left over bytes at the end of the buffer if (size & 3) { u8 *src1 = &((u8*)inputbuffer)[size & ~3]; u8 *end1 = &((u8*)inputbuffer)[size]; u8 *dst1 = &((u8*)outputbuffer)[size & ~3]; // Process the data while (src1 < end1) { u8 s = *src1++; *dst1++ ^= L[s]; } } #else // Treat the buffers as arrays of 16-bit Galois values. Galois8 *src = (Galois8 *)inputbuffer; Galois8 *end = (Galois8 *)&((u8*)inputbuffer)[size]; Galois8 *dst = (Galois8 *)outputbuffer; // Process the data while (src < end) { *dst++ += *src++ * factor; } #endif return eSuccess; } //////////////////////////////////////////////////////////////////////////////////////////// // Set which of the source files are present and which are missing // and compute the base values to use for the vandermonde matrix. bool ReedSolomon::SetInput(const vector &present) { inputcount = (u32)present.size(); datapresentindex = new u32[inputcount]; datamissingindex = new u32[inputcount]; database = new G::ValueType[inputcount]; unsigned int logbase = 0; for (unsigned int index=0; index= G::Limit) { cerr << "Too many input blocks for Reed Solomon matrix." << endl; return false; } G::ValueType base = G(logbase++).ALog(); database[index] = base; } return true; } // Record that the specified number of source files are all present // and compute the base values to use for the vandermonde matrix. bool ReedSolomon::SetInput(u32 count) { inputcount = count; datapresentindex = new u32[inputcount]; datamissingindex = new u32[inputcount]; database = new G::ValueType[inputcount]; unsigned int logbase = 0; for (unsigned int index=0; index= G::Limit) { cerr << "Too many input blocks for Reed Solomon matrix." << endl; return false; } G::ValueType base = G(logbase++).ALog(); database[index] = base; } return true; } bool ReedSolomon::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer) { // Look up the appropriate element in the RS matrix Galois16 factor = leftmatrix[outputindex * (datapresent + datamissing) + inputindex]; // Do nothing if the factor happens to be 0 if (factor == 0) return eSuccess; #ifdef LONGMULTIPLY // The 8-bit long multiplication tables Galois16 *table = glmt->tables; // Split the factor into Low and High bytes unsigned int fl = (factor >> 0) & 0xff; unsigned int fh = (factor >> 8) & 0xff; // Get the four separate multiplication tables Galois16 *LL = &table[(0*256 + fl) * 256 + 0]; // factor.low * source.low Galois16 *LH = &table[(1*256 + fl) * 256 + 0]; // factor.low * source.high Galois16 *HL = &table[(1*256 + 0) * 256 + fh]; // factor.high * source.low Galois16 *HH = &table[(2*256 + fh) * 256 + 0]; // factor.high * source.high // Combine the four multiplication tables into two unsigned int L[256]; unsigned int H[256]; #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int *pL = &L[0]; unsigned int *pH = &H[0]; #else unsigned int *pL = &H[0]; unsigned int *pH = &L[0]; #endif for (unsigned int i=0; i<256; i++) { #if __BYTE_ORDER == __LITTLE_ENDIAN *pL = *LL + *HL; #else unsigned int temp = *LL + *HL; *pL = (temp >> 8) & 0xff | (temp << 8) & 0xff00; #endif pL++; LL++; HL+=256; #if __BYTE_ORDER == __LITTLE_ENDIAN *pH = *LH + *HH; #else temp = *LH + *HH; *pH = (temp >> 8) & 0xff | (temp << 8) & 0xff00; #endif pH++; LH++; HH++; } // Treat the buffers as arrays of 32-bit unsigned ints. u32 *src = (u32 *)inputbuffer; u32 *end = (u32 *)&((u8*)inputbuffer)[size]; u32 *dst = (u32 *)outputbuffer; // Process the data while (src < end) { u32 s = *src++; // Use the two lookup tables computed earlier //#if __BYTE_ORDER == __LITTLE_ENDIAN u32 d = *dst ^ (L[(s >> 0) & 0xff] ) ^ (H[(s >> 8) & 0xff] ) ^ (L[(s >> 16)& 0xff] << 16) ^ (H[(s >> 24)& 0xff] << 16); *dst++ = d; //#else // *dst++ ^= (L[(s >> 8) & 0xff] ) // ^ (H[(s >> 0) & 0xff] ) // ^ (L[(s >> 24)& 0xff] << 16) // ^ (H[(s >> 16)& 0xff] << 16); //#endif } #else // Treat the buffers as arrays of 16-bit Galois values. // BUG: This only works for __LITTLE_ENDIAN Galois16 *src = (Galois16 *)inputbuffer; Galois16 *end = (Galois16 *)&((u8*)inputbuffer)[size]; Galois16 *dst = (Galois16 *)outputbuffer; // Process the data while (src < end) { *dst++ += *src++ * factor; } #endif return eSuccess; } par2cmdline-0.4/reedsolomon.h0000644000000000000000000003707710037507405011722 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __REEDSOLOMON_H__ #define __REEDSOLOMON_H__ // The ReedSolomon object is used to calculate and store the matrix // used during recovery block creation or data block reconstruction. // // During initialisation, one RSOutputRow object is created for each // recovery block that either needs to be created or is available for // use. class RSOutputRow { public: RSOutputRow(void) {}; RSOutputRow(bool _present, u16 _exponent) : present(_present), exponent(_exponent) {} public: bool present; u16 exponent; }; template class ReedSolomon { public: typedef g G; ReedSolomon(void); ~ReedSolomon(void); // Set which input blocks are present or missing bool SetInput(const vector &present); // Some input blocks are present bool SetInput(u32 count); // All input blocks are present // Set which output block are available or need to be computed bool SetOutput(bool present, u16 exponent); bool SetOutput(bool present, u16 lowexponent, u16 highexponent); // Compute the RS Matrix bool Compute(CommandLine::NoiseLevel noiselevel); // Process a block of data bool Process(size_t size, // The size of the block of data u32 inputindex, // The column in the RS matrix const void *inputbuffer, // Buffer containing input data u32 outputindex, // The row in the RS matrix void *outputbuffer); // Buffer containing output data protected: // Perform Gaussian Elimination bool GaussElim(CommandLine::NoiseLevel noiselevel, unsigned int rows, unsigned int leftcols, G *leftmatrix, G *rightmatrix, unsigned int datamissing); protected: u32 inputcount; // Total number of input blocks u32 datapresent; // Number of input blocks that are present u32 datamissing; // Number of input blocks that are missing u32 *datapresentindex; // The index numbers of the data blocks that are present u32 *datamissingindex; // The index numbers of the data blocks that are missing typename G::ValueType *database;// The "base" value to use for each input block u32 outputcount; // Total number of output blocks u32 parpresent; // Number of output blocks that are present u32 parmissing; // Number of output blocks that are missing u32 *parpresentindex; // The index numbers of the output blocks that are present u32 *parmissingindex; // The index numbers of the output blocks that are missing vector outputrows; // Details of the output blocks G *leftmatrix; // The main matrix // When the matrices are initialised: values of the form base ^ exponent are // stored (where the base values are obtained from database[] and the exponent // values are obtained from outputrows[]). #ifdef LONGMULTIPLY GaloisLongMultiplyTable *glmt; // A multiplication table used by Process() #endif }; template inline ReedSolomon::ReedSolomon(void) { inputcount = 0; datapresent = 0; datamissing = 0; datapresentindex = 0; datamissingindex = 0; database = 0; outputrows.empty(); outputcount = 0; parpresent = 0; parmissing = 0; parpresentindex = 0; parmissingindex = 0; leftmatrix = 0; #ifdef LONGMULTIPLY glmt = new GaloisLongMultiplyTable; #endif } template inline ReedSolomon::~ReedSolomon(void) { delete [] datapresentindex; delete [] datamissingindex; delete [] database; delete [] parpresentindex; delete [] parmissingindex; delete [] leftmatrix; #ifdef LONGMULTIPLY delete glmt; #endif } u32 gcd(u32 a, u32 b); // Record whether the recovery block with the specified // exponent values is present or missing. template inline bool ReedSolomon::SetOutput(bool present, u16 exponent) { // Store the exponent and whether or not the recovery block is present or missing outputrows.push_back(RSOutputRow(present, exponent)); outputcount++; // Update the counts. if (present) { parpresent++; } else { parmissing++; } return true; } // Record whether the recovery blocks with the specified // range of exponent values are present or missing. template inline bool ReedSolomon::SetOutput(bool present, u16 lowexponent, u16 highexponent) { for (unsigned int exponent=lowexponent; exponent<=highexponent; exponent++) { if (!SetOutput(present, exponent)) return false; } return true; } // Construct the Vandermonde matrix and solve it if necessary template inline bool ReedSolomon::Compute(CommandLine::NoiseLevel noiselevel) { u32 outcount = datamissing + parmissing; u32 incount = datapresent + datamissing; if (datamissing > parpresent) { cerr << "Not enough recovery blocks." << endl; return false; } else if (outcount == 0) { cerr << "No output blocks." << endl; return false; } if (noiselevel > CommandLine::nlQuiet) cout << "Computing Reed Solomon matrix." << endl; /* Layout of RS Matrix: parpresent datapresent datamissing datamissing parmissing / | \ / | \ parpresent | (ppi[row])| | | (ppi[row])| | datamissing | ^ | I | | ^ | 0 | |(dpi[col]) | | |(dmi[col]) | | +---------------------+-------------+ +---------------------+-----------+ | (pmi[row])| | | (pmi[row])| | parmissing | ^ | 0 | | ^ | I | |(dpi[col]) | | |(dmi[col]) | | \ | / \ | / */ // Allocate the left hand matrix leftmatrix = new G[outcount * incount]; memset(leftmatrix, 0, outcount * incount * sizeof(G)); // Allocate the right hand matrix only if we are recovering G *rightmatrix = 0; if (datamissing > 0) { rightmatrix = new G[outcount * outcount]; memset(rightmatrix, 0, outcount *outcount * sizeof(G)); } // Fill in the two matrices: vector::const_iterator outputrow = outputrows.begin(); // One row for each present recovery block that will be used for a missing data block for (unsigned int row=0; row CommandLine::nlQuiet) { int progress = row * 1000 / (datamissing+parmissing); cout << "Constructing: " << progress/10 << '.' << progress%10 << "%\r" << flush; } // Get the exponent of the next present recovery block while (!outputrow->present) { outputrow++; } u16 exponent = outputrow->exponent; // One column for each present data block for (unsigned int col=0; col 0) { // One column for each missing data block for (unsigned int col=0; col CommandLine::nlQuiet) { int progress = (row+datamissing) * 1000 / (datamissing+parmissing); cout << "Constructing: " << progress/10 << '.' << progress%10 << "%\r" << flush; } // Get the exponent of the next missing recovery block while (outputrow->present) { outputrow++; } u16 exponent = outputrow->exponent; // One column for each present data block for (unsigned int col=0; col 0) { // One column for each missing data block for (unsigned int col=0; col CommandLine::nlQuiet) cout << "Constructing: done." << endl; // Solve the matrices only if recovering data if (datamissing > 0) { // Perform Gaussian Elimination and then delete the right matrix (which // will no longer be required). bool success = GaussElim(noiselevel, outcount, incount, leftmatrix, rightmatrix, datamissing); delete [] rightmatrix; return success; } return true; } // Use Gaussian Elimination to solve the matrices template inline bool ReedSolomon::GaussElim(CommandLine::NoiseLevel noiselevel, unsigned int rows, unsigned int leftcols, G *leftmatrix, G *rightmatrix, unsigned int datamissing) { if (noiselevel == CommandLine::nlDebug) { for (unsigned int row=0; row8?4:2) << setfill('0') << (unsigned int)leftmatrix[row*leftcols+col]; } cout << ((row==0) ? " \\ /" : (row==rows-1) ? " / \\" : " | |"); for (unsigned int col=0; col8?4:2) << setfill('0') << (unsigned int)rightmatrix[row*rows+col]; } cout << ((row==0) ? " \\" : (row==rows-1) ? " /" : " | |"); cout << endl; cout << dec << setw(0) << setfill(' '); } } // Because the matrices being operated on are Vandermonde matrices // they are guaranteed not to be singular. // Additionally, because Galois arithmetic is being used, all calulations // involve exact values with no loss of precision. It is therefore // not necessary to carry out any row or column swapping. // Solve one row at a time int progress = 0; // For each row in the matrix for (unsigned int row=0; row CommandLine::nlQuiet) { int newprogress = (row*rows+row2) * 1000 / (datamissing*rows); if (progress != newprogress) { progress = newprogress; cout << "Solving: " << progress/10 << '.' << progress%10 << "%\r" << flush; } } if (row != row2) { // Get the scaling factor for this row. G scalevalue = rightmatrix[row2 * rows + row]; if (scalevalue == 1) { // If the scaling factor happens to be 1, just subtract rows for (unsigned int col=0; col CommandLine::nlQuiet) cout << "Solving: done." << endl; if (noiselevel == CommandLine::nlDebug) { for (unsigned int row=0; row8?4:2) << setfill('0') << (unsigned int)leftmatrix[row*leftcols+col]; } cout << ((row==0) ? " \\ /" : (row==rows-1) ? " / \\" : " | |"); for (unsigned int col=0; col8?4:2) << setfill('0') << (unsigned int)rightmatrix[row*rows+col]; } cout << ((row==0) ? " \\" : (row==rows-1) ? " /" : " | |"); cout << endl; cout << dec << setw(0) << setfill(' '); } } return true; } #endif // __REEDSOLOMON_H__ par2cmdline-0.4/verificationhashtable.cpp0000644000000000000000000000641007664453175014270 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif VerificationHashTable::VerificationHashTable(void) { hashmask = 0; hashtable = 0; } VerificationHashTable::~VerificationHashTable(void) { // Destroy the hash table if (hashtable) { for (unsigned int entry=0; entry<=hashmask; entry++) { delete hashtable[entry]; } } delete [] hashtable; } // Allocate the hash table with a reasonable size void VerificationHashTable::SetLimit(u32 limit) { // Pick a good size for the hash table hashmask = 256; while (hashmask < limit && hashmask < 65536) { hashmask <<= 1; } // Allocate and clear the hash table hashtable = new VerificationHashEntry*[hashmask]; memset(hashtable, 0, hashmask * sizeof(hashtable[0])); hashmask--; } // Load data from a verification packet void VerificationHashTable::Load(Par2RepairerSourceFile *sourcefile, u64 blocksize) { VerificationHashEntry *preventry = 0; // Get information from the sourcefile VerificationPacket *verificationpacket = sourcefile->GetVerificationPacket(); u32 blockcount = verificationpacket->BlockCount(); // Iterate throught the data blocks for the source file and the verification // entries in the verification packet. vector::iterator sourceblocks = sourcefile->SourceBlocks(); const FILEVERIFICATIONENTRY *verificationentry = verificationpacket->VerificationEntry(0); u32 blocknumber = 0; while (blocknumberInsert(&hashtable[entry->Checksum() & hashmask]); // Make the previous entry point forwards to this one if (preventry) { preventry->Next(entry); } preventry = entry; ++blocknumber; ++sourceblocks; ++verificationentry; } } par2cmdline-0.4/verificationhashtable.h0000644000000000000000000003215107667105444013732 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __VERIFICATIONHASHTABLE_H__ #define __VERIFICATIONHASHTABLE_H__ class Par2RepairerSourceFile; class VerificationHashTable; // The VerificationHashEntry objects form the nodes of a binary trees stored // in a VerificationHashTable object. // There is one VerificationHashEntry object for each data block in the original // source files. class VerificationHashEntry { public: VerificationHashEntry(Par2RepairerSourceFile *_sourcefile, DataBlock *_datablock, bool _firstblock, const FILEVERIFICATIONENTRY *_verificationentry) { sourcefile = _sourcefile; datablock = _datablock; firstblock = _firstblock; crc = _verificationentry->crc; hash = _verificationentry->hash; left = right = same = next = 0; } ~VerificationHashEntry(void) { delete left; delete right; delete same; } // Insert the current object is a child of the specified parent void Insert(VerificationHashEntry **parent); // Search (starting at the specified parent) for an object with a matching crc static const VerificationHashEntry* Search(const VerificationHashEntry *entry, u32 crc); // Search (starting at the specified parent) for an object with a matching hash static const VerificationHashEntry* Search(const VerificationHashEntry *entry, const MD5Hash &hash); // Comparison operators for searching bool operator <(const VerificationHashEntry &r) const { return crc < r.crc || crc == r.crc && hash < r.hash; } bool operator >(const VerificationHashEntry &r) const { return crc > r.crc || crc == r.crc && hash > r.hash; } bool operator ==(const VerificationHashEntry &r) const { return crc == r.crc && hash == r.hash; } bool operator <=(const VerificationHashEntry &r) const {return !operator>(r);} bool operator >=(const VerificationHashEntry &r) const {return !operator<(r);} bool operator !=(const VerificationHashEntry &r) const {return !operator==(r);} // Data Par2RepairerSourceFile* SourceFile(void) const {return sourcefile;} const DataBlock* GetDataBlock(void) const {return datablock;} bool FirstBlock(void) const {return firstblock;} // Set/Check the associated datablock void SetBlock(DiskFile *diskfile, u64 offset) const; bool IsSet(void) const; u32 Checksum(void) const {return crc;} const MD5Hash& Hash(void) const {return hash;} VerificationHashEntry* Same(void) const {return same;} VerificationHashEntry* Next(void) const {return next;} void Next(VerificationHashEntry *_next) {next = _next;} protected: // Data Par2RepairerSourceFile *sourcefile; DataBlock *datablock; bool firstblock; u32 crc; MD5Hash hash; protected: // Binary tree VerificationHashEntry *left; VerificationHashEntry *right; // Linked list of entries with the same crc and hash VerificationHashEntry *same; // Linked list of entries in sequence for same file VerificationHashEntry *next; }; inline void VerificationHashEntry::SetBlock(DiskFile *diskfile, u64 offset) const { datablock->SetLocation(diskfile, offset); } inline bool VerificationHashEntry::IsSet(void) const { return datablock->IsSet(); } // Insert a new entry in the tree inline void VerificationHashEntry::Insert(VerificationHashEntry **parent) { while (*parent) { if (**parent < *this) { parent = &(*parent)->right; } else if (**parent > *this) { parent = &(*parent)->left; } else { break; } } while (*parent) { parent = &(*parent)->same; } *parent = this; } // Search the tree for an entry with the correct crc inline const VerificationHashEntry* VerificationHashEntry::Search(const VerificationHashEntry *entry, u32 crc) { while (entry) { if (entry->crc < crc) { entry = entry->right; } else if (entry->crc > crc) { entry = entry->left; } else { break; } } return entry; } // Search the tree for an entry with the correct hash inline const VerificationHashEntry* VerificationHashEntry::Search(const VerificationHashEntry *entry, const MD5Hash &hash) { u32 crc = entry->crc; while (entry) { if (entry->crc < crc || entry->crc == crc && entry->hash < hash) { entry = entry->right; } else if (entry->crc > crc || entry->crc == crc && entry->hash > hash) { entry = entry->left; } else { break; } } return entry; } // The VerificationHashTable object contains all of the VerificationHashEntry objects // and is used to find matches for blocks of data in a target file that is being // scanned. // It is initialised by loading data from all available verification packets for the // source files. class VerificationHashTable { public: VerificationHashTable(void); ~VerificationHashTable(void); void SetLimit(u32 limit); // Load the data from the verification packet void Load(Par2RepairerSourceFile *sourcefile, u64 blocksize); // Try to find a match. // nextentry - The entry which we expect to find next. This is used // when a sequence of matches are found. // sourcefile - Which source file we would prefer to find a match for // if there are more than one possible match (with the // same crc and hash). // checksummer - Provides the crc and hash values being tested. // duplicate - Set on return if the match would have been valid except // for the fact that the block has already been found. const VerificationHashEntry* FindMatch(const VerificationHashEntry *nextentry, const Par2RepairerSourceFile *sourcefile, FileCheckSummer &checksummer, bool &duplicate) const; // Look up based on the block crc const VerificationHashEntry* Lookup(u32 crc) const; // Continue lookup based on the block hash const VerificationHashEntry* Lookup(const VerificationHashEntry *entry, const MD5Hash &hash); protected: VerificationHashEntry **hashtable; unsigned int hashmask; }; // Search for an entry with the specified crc inline const VerificationHashEntry* VerificationHashTable::Lookup(u32 crc) const { if (hashmask) { return VerificationHashEntry::Search(hashtable[crc & hashmask], crc); } return 0; } // Search for an entry with the specified hash inline const VerificationHashEntry* VerificationHashTable::Lookup(const VerificationHashEntry *entry, const MD5Hash &hash) { return VerificationHashEntry::Search(entry, hash); } inline const VerificationHashEntry* VerificationHashTable::FindMatch(const VerificationHashEntry *suggestedentry, const Par2RepairerSourceFile *sourcefile, FileCheckSummer &checksummer, bool &duplicate) const { duplicate = false; // Get the current checksum from the checksummer u32 crc = checksummer.Checksum(); MD5Hash hash; bool havehash = false; // Do we know what the next entry should be if (0 != suggestedentry) { // Is the suggested match supposed to be the last one in the file if (suggestedentry->Next() == 0) { // How long should the last block be u64 length = suggestedentry->GetDataBlock()->GetLength(); // Get a short checksum from the checksummer u32 checksum = checksummer.ShortChecksum(length); // Is the checksum correct if (checksum == suggestedentry->Checksum()) { // Get a short hash from the checksummer hash = checksummer.ShortHash(length); // If the hash matches as well, then return it if (hash == suggestedentry->Hash()) { return suggestedentry; } } } // If the suggested entry has not already been found, compare the checksum else if (!suggestedentry->IsSet() && suggestedentry->Checksum() == crc) { // Get the hash value from the checksummer havehash = true; hash = checksummer.Hash(); // If the hash value matches, then return it. if (hash == suggestedentry->Hash()) { return suggestedentry; } } } // Look for other possible matches for the checksum const VerificationHashEntry *nextentry = VerificationHashEntry::Search(hashtable[crc & hashmask], crc); if (0 == nextentry) return 0; // If we don't have the hash yet, get it if (!havehash) { hash = checksummer.Hash(); } // Look for an entry with a matching hash nextentry = VerificationHashEntry::Search(nextentry, hash); if (0 == nextentry) return 0; // Is there one match with the same checksum and hash, or many if (nextentry->Same() == 0) { // If the match is for a block that is part of a target file // for which we already have a complete match, then don't // return it. if (nextentry->SourceFile()->GetCompleteFile() != 0) { duplicate = true; return 0; } // If we are close to the end of the file and the block // length is wrong, don't return it because it is an // invalid match if (checksummer.ShortBlock() && checksummer.BlockLength() != nextentry->GetDataBlock()->GetLength()) { return 0; } // If the match was at the start of the file and it is the first // block for a target file, then return it. if (nextentry->FirstBlock() && checksummer.Offset() == 0) { return nextentry; } // Was this match actually the one which had originally been suggested // but which has presumably already been found if (nextentry == suggestedentry) { // Was the existing match in the same file as the new match if (nextentry->IsSet() && nextentry->GetDataBlock()->GetDiskFile() == checksummer.GetDiskFile()) { // Yes. Don't return it duplicate = true; return 0; } else { // No, it was in a different file. Return it. // This ensures that we can find a perfect match for a target // file even if some of the blocks had already been found // in a different file. return nextentry; } } else { // return it only if it has not already been used if (nextentry->IsSet()) { duplicate = true; return 0; } return nextentry; } } // Do we prefer to match entries for a particular source file if (0 != sourcefile) { const VerificationHashEntry *currententry = nextentry; nextentry = 0; // We don't want entries for the wrong source file, ones that // have already been matched, or ones that are the wrong length while (currententry && (currententry->SourceFile() != sourcefile || currententry->IsSet() || checksummer.ShortBlock() && checksummer.BlockLength() != currententry->GetDataBlock()->GetLength() ) ) { // If we found an unused entry (which was presumably for the wrong // source file) remember it (providing it is the correct length). if (0 == nextentry && !(currententry->IsSet() || checksummer.ShortBlock() && checksummer.BlockLength() != currententry->GetDataBlock()->GetLength() ) ) { nextentry = currententry; } currententry = currententry->Same(); } // If we found an unused entry for the source file we want, return it if (0 != currententry) return currententry; } // Check for an unused entry which is the correct length while (nextentry && (nextentry->IsSet() || checksummer.ShortBlock() && checksummer.BlockLength() != nextentry->GetDataBlock()->GetLength() ) ) { nextentry = nextentry->Same(); } // Return what we have found if (nextentry == 0) { duplicate = true; } return nextentry; } #endif // __VERIFICATIONHASHTABLE_H__ par2cmdline-0.4/verificationpacket.cpp0000644000000000000000000000657307664453176013617 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "par2cmdline.h" #ifdef _MSC_VER #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #endif // Create a packet large enough for the specified number of blocks bool VerificationPacket::Create(u32 _blockcount) { blockcount = _blockcount; // Allocate a packet large enough to hold the required number of verification entries. FILEVERIFICATIONPACKET *packet = (FILEVERIFICATIONPACKET*)AllocatePacket(sizeof(FILEVERIFICATIONPACKET) + blockcount * sizeof(FILEVERIFICATIONENTRY)); // Record everything we know in the packet. packet->header.magic = packet_magic; packet->header.length = packetlength; //packet->header.hash; // Not known yet //packet->header.setid; // Not known yet packet->header.type = fileverificationpacket_type; //packet->fileid; // Not known yet //packet->entries; // Not known yet return true; } void VerificationPacket::FileId(const MD5Hash &fileid) { assert(packetdata != 0); // Store the fileid in the packet. ((FILEVERIFICATIONPACKET*)packetdata)->fileid = fileid; } void VerificationPacket::SetBlockHashAndCRC(u32 blocknumber, const MD5Hash &hash, u32 crc) { assert(packetdata != 0); assert(blocknumber < blockcount); // Store the block hash and block crc in the packet. FILEVERIFICATIONENTRY &entry = ((FILEVERIFICATIONPACKET*)packetdata)->entries[blocknumber]; entry.hash = hash; entry.crc = crc; } bool VerificationPacket::Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header) { // Is the packet large enough if (header.length <= sizeof(FILEVERIFICATIONPACKET)) { return false; } // Does the packet have a whole number of verification records if (0 < ((header.length - sizeof(FILEVERIFICATIONPACKET)) % sizeof(FILEVERIFICATIONENTRY))) { return false; } // Is the packet too large if (header.length > sizeof(FILEVERIFICATIONPACKET) + 32768 * sizeof(FILEVERIFICATIONENTRY)) { return false; } // Allocate the packet FILEVERIFICATIONPACKET *packet = (FILEVERIFICATIONPACKET*)AllocatePacket((size_t)header.length); packet->header = header; // How many blocks are there blockcount = (u32)((((FILEVERIFICATIONPACKET*)packetdata)->header.length - sizeof(FILEVERIFICATIONPACKET)) / sizeof(FILEVERIFICATIONENTRY)); // Read the rest of the packet return diskfile->Read(offset + sizeof(PACKET_HEADER), &packet->fileid, (size_t)packet->header.length - sizeof(PACKET_HEADER)); } par2cmdline-0.4/verificationpacket.h0000644000000000000000000000502407664453177013253 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0. // // Copyright (c) 2003 Peter Brian Clements // // par2cmdline 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. // // par2cmdline 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __VERIFICATIONPACKET_H__ #define __VERIFICATIONPACKET_H__ // The file verification packet stores details that allow individual blocks // of valid data within a damaged file to be identified. class VerificationPacket : public CriticalPacket { public: // Construct the packet VerificationPacket(void) {}; ~VerificationPacket(void) {}; // Create a packet large enough for the specified number of blocks bool Create(u32 blockcount); // Set the fileid (computed from the file description packet). void FileId(const MD5Hash &fileid); // Set the block hash and block crc for a specific data block. void SetBlockHashAndCRC(u32 blocknumber, const MD5Hash &hash, u32 crc); // Load a verification packet from a specified file bool Load(DiskFile *diskfile, u64 offset, PACKET_HEADER &header); // Get the FileId const MD5Hash& FileId(void) const; // Get the block count u32 BlockCount(void) const; // Get a specific verification entry const FILEVERIFICATIONENTRY* VerificationEntry(u32 blocknumber) const; protected: u32 blockcount; }; inline const MD5Hash& VerificationPacket::FileId(void) const { assert(packetdata != 0); return ((FILEVERIFICATIONPACKET*)packetdata)->fileid; } inline u32 VerificationPacket::BlockCount(void) const { assert(packetdata != 0); return blockcount; } inline const FILEVERIFICATIONENTRY* VerificationPacket::VerificationEntry(u32 blocknumber) const { assert(packetdata != 0); // return &((FILEVERIFICATIONPACKET*)packetdata)->entries()[blocknumber]; return &((FILEVERIFICATIONPACKET*)packetdata)->entries[blocknumber]; } #endif // __VERIFICATIONPACKET_H__ par2cmdline-0.4/PORTING0000644000000000000000000000137307664453171010272 This version of par2cmdline has been compiled and tested on the following compilers and operating systems: MS Visual Studio.NET on Windows XP gcc 3.2 on CygWin 1.3.22 gcc 3.2.2 on Red Hat Linux 9.0 If you wish to compile par2cmdline under a different environent, then you should start by trying to compile with the supplied Makefile. If you get compile errors, then the most likely place you will need to make changes will be in par2cmdline.h, diskfile.h, and diskfile.cpp. See the file ROADMAP for details of what each of the source files is used for. If you succesfully port par2cmdline, it would be appreciated if you could post the details on the parchive web site at http://sourceforge.net/parchive.par2cmdline-0.4/ROADMAP0000644000000000000000000001441207664453174010234 commandline.h / commandline.cpp class CommandLine; This class is used to process the command line arguments passed to par2cmdline. Basic verification is done to ensure that invalid combinations of options are not used and that files exist. crc.h / crc.cpp u32 CRCUpdateChar(u32 crc, u8 ch); u32 CRCUpdateBlock(u32 crc, size_t length, const void *buffer); u32 CRCUpdateBlock(u32 crc, size_t length); void GenerateWindowTable(u64 window, u32 (&windowtable)[256]); u32 ComputeWindowMask(u64 window); u32 CRCSlideChar(u32 crc, u8 chNew, u8 chOld, const u32 (&windowtable)[256]); These functions are used to calculate and verify the CCITT CRC32 values for blocks of data in data files. The latter three functions allow the rapid computation of the crc for data in a sliding window. creatorpacket.h / creatorpacket.cpp class CreatorPacket; This class is used to read and write "Creator Packets" to a recovery file. criticalpacket.h / criticalpacket.cpp class CriticalPacket; class CriticalPacketEntry; CriticalPacket is the base class for DesriptionPacket, VerificationPacket, MainPacket, and CreatorPacket. CriticalPacket encapsulates memory allocation for the packet, computation of the packet hash and writing the packet to disk. CriticalPacketEntry is used to record that a copy of a specific critical packet will be written to a particular file at a specific offset. datablock.h / datablock.cpp class DataBlock; Objects of this type are used to track blocks of data that belong to different files. When data is read from or written to a datablock, it calculates the correct file offset and length to use. descriptionpacket.h / descriptionpacket.cpp class DescriptionPacket; This class is used to read and write "File Description Packets" to a recovery file. The class can compute the file id for the file when creating recovery files and will verify that the packet is ok when it is loaded from a recovery file. diskfile.h / diskfile.cpp class DiskFile; class DiskFileMap; The DiskFile class encapsulates all file access. Each object of this type represents on file that par2cmdline is using, and references to it are used in any other object that needs to refer to a file. The DiskFileMap class is used to track which files have been processed. filechecksummer.h / filechecksummer.cpp class FileCheckSummer; The FileCheckSummer is used to compute the CRC and HASH of a sliding window onto a data file. The CRC is updated continuously as the window is slid allong the file, and the HASH is only calculated when it is needed. galois.h / galois.cpp class Galois; class GaloisTable; class GaloisLongMultiplyTable; The Galois object is used for galois arithmetic. GaloisTable encapsulates the log and antilog tables used for fast multiplation and division, and GaloisLongMultiplyTable is used by the ReedSolomon object to allow rapid multiplication of a block of data by the same value. mainpacket.h / mainpacket.cpp class MainPacket; The MainPacket is used to read and write a "Main Packet" to and from a recovery file. md5.h / md5.cpp class MD5Hash; class MD5Context; MD5Context objects are used to calculate the hash of a block of data. The resulting hash value is then stored in an MD5Hash object. par2cmdline.h / par2cmdline.cpp int main(int argc, char *argv[]); par2cmdline.cpp defines the main() function which is responsible for creating a CommandLine object to parse the command line parameters, and then to create either a Par2Creator or a Par2Repairer to either create recovery files or use them to verify and repair data files. par2cmdline.h contains #include lines for all required header files, as well as a number of type definitions. par2creator.h / par2creator.cpp class Par2Creator; This class encapsulates all of the procedures required to create recovery files from a set of data files. par2creatorsourcefile.h / par2creatorsourcefile.cpp class Par2CreatorSourceFile; Each object of this type represent one of the data files for which recovery files are to be created. It handles creation of a DescriptionPacket and a VerificationPacket, computation of the full file hash and 16k hash values and the calculation and recording of the crc and hash values for each data block withint the file. par2fileformat.h / par2fileformat.cpp struct PACKET_HEADER; struct FILEVERIFICATIONPACKET; struct FILEDESCRIPTIONPACKET; struct MAINPACKET; struct CREATORPACKET; struct RECOVERYBLOCKPACKET; These structures define the exact format used to store the various packets in a recovery file. par2repairer.h / par2repairer.cpp class Par2Repairer; This class encapsulates all of the procedures required to use a set of recovery files to verify and repair the data files for which they were created. par2repairersourcefile.h / par2repairersourcefile.cpp class Par2RepairerSourceFile; Each object of this class represents one of the data files that is being verified and repaired. It has a copy of the description packet and verification packet from the recovery files, and keeps track of exactly which disk files contain data blocks that belong to it. recoverypacket.h / recoverypacket.cpp class RecoveryPacket; This class is used to read and write the header of a Recovery Packet. If contains a DataBlock object which is used to read and write data to or from the rest of the recovery packet. verificationhashtable.h / verificationhashtable.cpp class VerificationHashTable; class VerificationHashEntry; The VerificationHashTable is to store details obtained from all of the verification packets. It is used to check whether or not the crc and hash values calculated by the FileCheckSummer match any of the data blocks from the data files. verificationpacket.h / verificationpacket.cpp class VerificationPacket; This class is used to read a write Verification Packets to and from recovery files. letype.h class leu32; class leu64; These two types are used by fileformat.h and are used to handle the type conversion between little endian and big endian numerical formats. par2cmdline-0.4/par2cmdline.sln0000644000000000000000000000161710037454612012131 Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "par2cmdline", "par2cmdline.vcproj", "{D0A94F83-495E-4FB2-AC33-9A3EC2CC263B}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {D0A94F83-495E-4FB2-AC33-9A3EC2CC263B}.Debug.ActiveCfg = Debug|Win32 {D0A94F83-495E-4FB2-AC33-9A3EC2CC263B}.Debug.Build.0 = Debug|Win32 {D0A94F83-495E-4FB2-AC33-9A3EC2CC263B}.Release.ActiveCfg = Release|Win32 {D0A94F83-495E-4FB2-AC33-9A3EC2CC263B}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal par2cmdline-0.4/par2cmdline.vcproj0000644000000000000000000001742310041756513012642 par2cmdline-0.4/testdata.tar.gz0000644000000000000000000014744607664453174012204 R>XSka"l0(݉CPQa^*^X؊-vww݉׮9?ٹgl32w_M* E( %@Z([ vD,Hdk+ I}LM>^^2USw2- K М k2w_M*j>"P" 1/mm?H%b[;k럷JDSQ4~2Kv7P~ue.eVd >$1,0dYlKv ET''(c)Wfam&IvBP(HBֶv?$kXl+y;NPk(?_T%Su;u(]R%@:z-?Wfac&IvBP(HBbk[D$I$Z`*#W&15xyTNJ_jR:PH ( @H-`X@S )ЪA"sY-ݤ2C( %@Fhgck+I$Vv"X`*#W&15xyTNJ/''%@J( @w]YPM+tʤZH(H$BKuvD,lSQ4~2Kv7P~I@JTRMg @rYzF+XIeR݇P$J$P!楍綝Db-m?o'I"Pk(?_T%Su;u(]EH!"@*a gM [@#Hi=!sYYIeR݇P$J$P!極Plmm'I$Vv"H`*#W&15xyTNJׯݫ *M ?@ $!sYTtʤZH(H$BKkNd'I$Vv"X`*#W&15xyTNJ/tT:RN9IX2w_T&M&P$J$P!楍F( vD,Hd+ I}LM>^^2USw 086GP.4 4MH+sʤBC( %@F"$kP$Hd' I}LM>^^2USwj@1x5#@WZ?TKO< 5J/H]djzyNt65 Z R ~_R]a.?+arR )>D47Q&8]HB`,K$;b9eL W&I-ںH(H$BK[ϻI$[H~;N, I}LM>^^2USwj@1͏Br\b&uoevwž t5[2kZť|lu_\[yOsy:aWɜm'2W XK@s[hrq۔"c{-s 2 >d2\#yFMhy;+nVTgo},rPam#nJ{2? h*&2WںH(H$BKX H%Bv" Lz@ʤ>//۩@5uh{H Ș6WzFx!~;;s;aO\{ :qƿ/̚Vq6GW#V:mt~5>U2gtI7z=L.R&ܖ9Zi~]v6^܂3 n?ȷϡo:L;WÈuQG8ZΊ.=[\;=8Tqvtþ :m~>nABmXO=6`ٳ٨8ڋI%nj)l?EٻӟnƋ &>ԽN`$*63bAׅ^難ʝf?h|ֿTѿ}뿵iÖ_G>QWn/ Yu0GM-].!^E$*_uE~Uw6SSqзadm-L֍1ԯۢC F+լܩ>6ӹ-lգ. [HC;&+;u4b#em,96 kzZW]s^jU'#[2mm_oG Oͣl_k/NlN%_|}bdO{Ol8Udz&Z64ǾT_>0빨{m=+Һd]g?0u2ol_k?lݯ7.]yaMnJ8~M[}X"V!-_J/X鴒<;YwZm(8i,e}%,rkXߣ7dQۈE] y✳N֐5[yl%mF7Og?z}}}l4f=~Z6n7/M)aݎlʔ /X_>Ed,u!eGGe?.FT}X-wM~vI6=i[];}ʯ]||\4ʗ!؏Ia8`@K[%ݭ f`G^-_tGv`9dImo߿ӄÞtq\fW.Efn4iF /hǝj;)Նow)ϭn=WMn`^Xܥ o(e}5%ߣ >s!h`ަVM5PO\V-wrjrȼr!GN'sd )yHv׭)W)\\0ǜV֓s1qy6/,kBխi#^;ln]}P˶o8 2J6\I&en )3ec+o\vWL[Ul-tݱ吲}ϭ1sZi'6gϦT3EtwϞ*=3T=坫l^j]C+6se5}%|* pz㗖Ⱦ5}_z/_jcO.3}6^YSL3gʾxw;حmit7j3MQIUP㲺C˻gّ<_S]~OW;kߏĻ˶WR~ ]pOcwIU|=Eټz=~򄞎ǻ)zbI,uy]mtֵq>:U=uk&'q?-^4i⹧|ߦ΅;6}>MH IkWZe}aIgG]*iRپ.~aSu}Q~BL1 cQv15d=C,{I4N.?k/dsꦰbe+Tjei#q5>~ފZ)!̰f[memG1LN[k~n˯*l_6+ ܹ*T~Vжwtvh:ۻp'τZOcW)WHٛ5m͙ ̒?Enq,o'8eI%҇>9a'6WAeNz׋?׵kqڢҥT=:cң]lUOzwB/}ܳ!`䋺W}-v+z P- YپZvӵ=I{Z}id!;?x,Mɺv=]8tMsoӧch'zn=Wo)8;FKH^>ʞ%5ܙ͸PdÂY-1ofek9!so3w W=/ }8{d {ǷHtTwD׶~ڜ2_ݻMJ:Olc''~'6oy,vÃj;Ob?r wpwnUv*am&w^m"T/ |򲯋\W|Qkσqi Vwֳ_Xjcǣ(NB g{X~ ~|Ѥ{\[΍(3qoog8kq\ڜhVb災.lm}#lTnÚ:v\mm0 _>Y&84F6ܑ!yߍ/YZzAn?sYNH X38l9=O-4QVMJ`}gӗ?>خ[xlypHomC y6]~GXش3_gyOE￷!ӧY/}V>4ūvSn仿'SۧK7;䐞;b?BW}TRC+Ga 7?"ٱm"(<'j.oQIoV!Zznܧ|z<[x}NMsɪm߭oѽ!#;wn:!͏.?0~}z+XIfȫN{uf-9 Mʡ_8yiBMk+ ޷̽;e&uh\b3O8ThI>WY)۷x7:w*ڢGωlǫ~'O}<&bc}?9bվ_TRoѿ(UcCu#]ʯsLs~јG?lhT˕ n;b?5ZrjG A'lR/t4c\iΞ:;,%E us2rvō^5Ǘ6y ձݽs`~cy,x.p^޷jM3bׇ^nR0ݧlUZ?/:ҽN׳zުhkF% 9n?bB vXVK_^pť`UYǴ?cnr&=pL?[C-/4zdPpa==1~!ޭx>QDn5|wxu}5];mJ_s 뒱w{'79&w"ϡ1;rTXAҷVP|P#G_ Jti.=Y3cwp#?׶?f8bC Aދ[\kKe^>Kw7Sׁ.P09̡`s(C P0B9̡`s(C P09̡`s(C P@Ę!2Zk?t%wٽ/̧no| M랺e}U-+(P.&["tK$/U#Xf1>slbj0ћFV&/R[QJSZճt;xGhͅ7Ga}Jxk%*띫VxA]}׀9*Q5{!bsTuiIY-RcOq[w>]FfStUW(mf!|R֡ʎ21zϗHjuđEBZrL\[Onkeeubsu{ІnX-Vm"oΚzB.rs73WMgsN˸kg:.n_l{m{&h>3}0`?90`?0`? eGc!mp-}Ckn\evѢzgg$AYyC$ŧeKh̗r[0nk Tk꿮=Θk;4Yޒ1.q g\8θpƅ3.qr g\8θpƅ3.q g\8θpƅʸp]!6B^_$/{Z 'ֶ\dFD^ ߈ݞVZ>ɯFP'g+eE9: .U?N3/5SQӧWV'1M9TQghUUϠV50 7E]-3kNtfR,,@YT:^3_-V] o̬ U L^JHFĭٺ~nMswp#9Y~HM8}K|e9tTG= s%!#[!z$+Vk.k鐌= 75\]rNh#o_wgg%I]Շ\J~rTIhyWN 5[Κ|VeIr;nLşm4&K{(o1σy`<<y0σyr`<<yycƎ5=A}Mײq#nj1E^9ҵU:}QUM_6ЅuڼINw}j]kYdqO~cdP}vYԨAc|5UuiMWƿޫUښEɶX^O*ooUU;txokTgZ^wkU{VCl蠨Zi,ߏHQ̕ĭVWtU+O[.A'S%ѵi+r5Fo;bMqy-3EosBSUQ:Q=1íB16\X]MOhyǽRY\CCo% N+%4 w]Sn/\MEᠸ3p[Z7kcaaaVθpƅ3.q g\8θ=.뺊_uJBkfޝjN?+p"V!zOBK~n-hÅiǭ?SUq;Q2NtF>i2ٮƱcm `m `m Eƅ3.q g\8θpƅ3.q){\xߟkg~!τ -E}}ܥ2/ť@f~]{5 -UWղ\X[cCM( %@Z(ܶH%Bml$bPC9?_?&SL]ob|j͚)^ܻPX?;.:rfƟ#idxZ"v*[Å2wV߂L϶tjh}kK3Hޤ8kРܿK;gi*J~rnPI4EѭO9kewPrkj7eOzǨ/wJȪϐ7@U,BkHM9Iz^?bʼF3e- EcUvU':hs}79MUZI|nYgg]%5&ڀZaJr-&-ٞ}u_UaBd\rjUə&ULY*I~MLh7sMr ~nN5ո=3O4?|豯&ݬwXυ\Xυ\Xυ\Rz.E`.s\mJ("_g)u (О;p46KVtEw[7?uܺtu'Xر 빰 빰 빰 빰 빰 빤\"Lj6ҷ;vߞm1"~̃Kuo5*'{%L~ ŇI޶wwV~루I!M1"26yZGP)|]|'w]4y̎gzX]4!Ȯ۔~I oueFURWwW^yl!vxmT5S )cRƗvqu{a]UwWL\[u^Ӆmh W*]E ;xhwR=[+M^s;q953ful tOh/WѰ664{lЬK7@MWvM3_W岚lewرkkkkkkkkkkȱFY[[塀GSun][C>6$|,ܥx[ʤnO~Ԑלw]. $O1/um[|=߿vus☭YNKqUi䶿^z>ZhLo3{w嚮}wخaEu+|Q 2%^V竪ߤj{v oT{["oiMͿBd{,!HjU烢/W]I߅/iu|ztANjvs$M. Ws]L\rn_C5M[uOo_,IDGK}hagtyUB;aΔqKWYٚQLyJ|sT5FN~N޷z,rΊ޹JnWgzj{j֊KoiPs~EHL-O5vhOE|c-ke ^AcΣbPB6gʒ6eGPZR*ҢBvj|P"T"") =c;wi^sѼ;MLs^w+Yx;n*dh7/FCƘh'uDzH>s 63?lG1Щ͖g7WХހ.mRnȋ,&òLHNW28!GY5rTbHeW2q?vNА;W,b- ,;[5Y5S̏P>mMۀqopo6rE4܄#nȺ.8BHuBYhkhkhkhkhk@hktFa ɭw3=tkq}$ksZYާ lH66Mhe ِpq\F2E 9n?72b)XK;\guא;JXl=hJ䜌K',Ļe5b#MFl_ kDDw0sLr.~4E3W]Ķqp%]> ܖm0V@ eHRѧD0SF}c| / }3As]_S>/?OM R.BS1+^Um꺶.3"DoG \N(Vۗ 5@[5@[5@[5@[5@[5@[5,ZMO9dUɽnU^&Ww-#L=W;ظPQYy:U5l8vl/UMMMQ}dUU竫kj P!`yl+! yX_Ӌ%=SW~0rEDX,9$Tbܑjh.{݁&Aȸ9Wfc!QJdDgL19>Qaޮٸ /BWwF b$wʙ<3BS's'ꌬC5VT'Wj&-DI֌huM/"8`:9S?A? 9!R,᯶"X!!yِ7QOeu/4RB>ENYn)I'kU$;%%+61k))m-=Š񘿞8n՝"֑DƲ2/畚H&PS<^I]rxוλhKÒ>=0q28B$ެ@/A/kA^˜YH;c=&iCՔX3;3AĴ5bmO4.FĹcwuHID(Dd$OgHm'Lj3IesO=o2̧S43촖OLj{W/ls M :ѕ8 $ދϧ0$J GU]Ž!4WǢ3,- !~BXÏ܊E[x_3iGmDdN1n l$Cy|]v J J$c.3۸WS֋DMMK1ޖ8K:G8jH!n^Sމ%F2H>jPt-^@.^u];Ĝ Q;.Y ٸdOy.!@/A/A/}/s"Emɣ&**WlM7Ś#Jq?zj~C#[*u_- _ZVӝ  !_.Dr+ZQ=ȊJti>kRUC[ih%X]9 "^EeJ2K3g'X$ ?t37AbއʏSòQ~QmG8i35x)]gG[wa6nzI=!KcHwHPm$*<ͽQkuUT#p6ǴpJ" O%CJL x#o>1>1}b|ke\3?7J0(M WF9 )]F@C'KR?"m98qo_ٮ2 0YZ)~Oo/*8f|/܃3na'ޕ! Y F~SɎ7[埱| Br~&R AʐDC#~4fCj߹KH'ӳ4Z͍42<.ܹ8;9ewq*ޒ\+%, NΩXaɿF V^cEe^h#OMao9ʊ ]vcc^s9^IƋmp73p?!ө""]vvuf>1>1>1/ČYodJnޥ|6ǚšB* meF5#|,{k! s  J_ R8B}!3SGJr%%<]_xR3Nh˨CԻ3`x-̑Zo?y4UvL<ˢ|G7R@E2-ETnX%?1zae}pRk+Н٘Ơiܘ`IZ8$f f WT3ʞz`?q /&a/YT$ ԔͩP|~lOn.p8.^﨓m~*iiVĠO ĠO ĠOL>1cInUkF도ƍcb?.7kX̣w'⺗3^۾U_O͉k\VCwi*SB 1K VI'Z}l.>ڭ:[lN"1 AAAČyp7笁36k1 k)~&B$L5jl=%%#On u%DY#^1 ;ZU˽^@tڶtFĉåoӈk/.@%M4u!982P8kԴ{yf̲F,6e)HV'# 2ڳ#? c b87!)  ?[Ҥs/Nnxn{ȋ ^}"a*b] `vaX1Ne0/`VԀז 9c+ĺ]k32>W[  jTw9*=^xՏ=u {I3u-p+bI'wPJBȽԭTX5*[*D,$JJ"%ERRڐBʒ6-9#f,f <<<1Ox>1ǪĤ9Y%E1:79=1J,rPr5߼cALcU*"`#,V~|c]#̺Oq<^JɸG})vMh[q4ou$Vq;qȥmZLP M!.~h} ior pM3s[PF(&6˩#bD}o@;h= ca3Jj|}791aWUZ]!1%R:9gx7F3Ji!X#ucK(#֣_ӑi]dStSzc{FQ;, Oqrx>1Ox>1T~nHyvcT7tt3[r䊯25P)*LIǂ noD..Jy0CqLP]37^z FD G`m+2- LT^ sk8ib/d@r(7WЮ}xP{b΍%$X5pD't,otot> ۍ^As+qJTD4v'$4[G)wގ7<'|ⱘOLysvt)z!ȔnN'2%p:n8 R% ,~'e_RY\qz@@VDЄ/ǜZPJ56Hv2WplJSʼ }Gs&(7M`|SᴆϤ!NU,|(^ 8i5z/ pE}cQ̳G!$SqD2!Z'){иCN@+6Fӂ u=RYj_4(3r:ZWTR{ߏ_?{#MKw A`Ñ=w|vhLɿpϢTZYH *y߻oxox>1Ox>1OLmVziyB7[*;jg|M]83ӅPt+M[XWڡJ(l?0Iq;0a9j(6ÂQjvpȘ??{cU`l7OX0mGV\[NKdG_ba{G8VSV e08d}u(;T(iLlHoG)GkJF`>4." |88 ;,O ɭݶ:VFHlޅr9i2<&˼EFZ787C #1dLEIFy~WwZ@ל(J-$1~D=:~p{Moxx|b<'7X3W+sAj,v؊0)ŝc4P*e_XX}!:"- }+:`f&acy67o_0]=> +8ڞm6KVmO;p~+q8PL4ZLSh G]d[Rw.$pDi=kw(chlMD[YhH}R,x1O<:I 3a)˩:Unǰ^M-xҏ+o,ѓ#TV%X} (6cz G?G𪚈P8eZmq-cl[kCa5@9) NJM\=I䧝 !SB(ބSɖ&!?0 _/FGq6pD%(m8RD}%<M`=$k pyFEԔɖ]>%4X$6RnYãse?AW2H ))l`Sk9z/ 7 yk;ѫZaږ8Ll{dS^D ctnv)9Fx|b<'|b+Ta~ptT|D}16PkXޘvUߌ%d9o> h3q%yuNP֖9yLߍelXfF#&q mQSzĎ?h凈 *à,gk,,xkS {׼knJ衕7I`?gy%rmx KYܴ`L"0('o-R =sG͔X\Yq%+g`!?4c$Hxv8>IsȬCG~QHx|nn!6VL`! hʺ«բXprny.DR[qb@Q +ƓD-͡6/Q6 YDf9 YV/Ovw"//yhkK;)pĚЧ&8%VScπGN0^|E4mdW2_CG $..3~RlH1OR}=g`n.jVTm{`0sie$]u0hATμڳ5HX79m`61Z5^2)[ J^-(am?BG*%)8MZm]E_Et3{N.FkŌ\qp3(q`S݃IFc#YwX0M ui8W9@+6`(ccFӬnsѯKc#>*ˠOIMc%1 i>G r$I3[;ht~ cοoN݌>VcFlz!6oJ~ w(baf"E~Ñ\ҳu7BF_hӎ?:Vz^*C3m2v8V9f'V`)`Aqz'Nf/D :Г|r-"MT~hgfѣ3t,4{mҞSֆ}PMm-KO@u_?lNX~tDj&J<%rԂ;O{v.Z|r5*qr#Ƹng.썲{Ug߃Γ%lsnHkjLX^%w?hBo浟W3}>e+-E^ ,m-Y]^+CFRBz6"[_u;)g!uV%MɡIlMas  ̹רo 鐧#{TG?@umZƾW'ݭ;ߗh:ayqK0;a6?GjrػpF݄DRVF6=2=B"[JdfdMdDFޔMξU[8o>7*W7\YN w9)ܝ39TfD8ZK[#!)g*cas؍43^iyS2cf촼3ďb=zo,Oξ}q:ݺ9pw#r3}sG=x>{, vc x^ٻ6_b&y9xɡ55k+[Ysʆ?ܽ@АnYuӯJkOߔs[kh[w.>8ЧLC{{H>\VA?W`tM W:` 1xhy/f2&o> pX  [; 5kv6mܩ%7dT,A=k`e4(knMBʍV.POwjۛ! eʿWf]6[JYO?f-ivn/ @ `{ Z hqQ:߮G RDY"anoxCY[$m)X=y=y."ޡ~coۓ^w8F5)EդƦ;#0oVJ}Tп΃Ou<T([G"-ȷ_Ɉ>^$f/_( _!siM<(=٬]qԋe:#qY%$w': T:%Y'N :vq*Wb;TR=Eڶ}Q#BS;.5LQ"x2# &2G]j2R*Q{Ř+QNI*;^94:Zx( " l"̲Dl1ㄯ#_*_\gYԪy<` 2#8Qww<f?7Ok3@z8tǤ*H3׏ݑߦ,)!>xlukAٕv* WGd$9$(+ms/[T0FB+AeOz1}ZIא-UQPf1*BKTfIjا`%Ч R",<{dr ?[BYsM#[oM0o:mdH*ArJ)ɥoގSNjL`j{e^=SCq~>}szNG~SeA"Iv/㿀)tc)xu̇$9}toAso1E,%{>_uZ0 Ls RyVnb\b5&8'̡é8C=ȁ0f|Z# β6]G tuCк[ġ&.ʶzv`[b渫w z/ ߖ*d-(E E 7Nmx(LeJIȡRbl"Ga":,w{xTYH%}Jij~:$ݛĉTdMgALFPf< ͐9fۡ) .>̥բ9P%@\ ;7I` }M^trYgͱ Wq'.c+ a< .[uMOdNi1O%'9v!8R6*>s6 (_ES 12 =5~Bgy$VsHqCDcL'JPxiUjirQߟi%1C :1x??wg4h8"RM>܏JqT9PCFh Ppw=7 iVJDyPu,z=,ZOA>S,LPzm$_7&Ƚi=V$OK?5iCdyV!ԍ8z28¦xC̯TFXFI$Z`) =fJJ}kJ *[djNy3 zB3=_~>Or.sK댯k +jDoj3`wBw ~ 1(ό0&\Pzs}av,=7Mt4lG8xH@qif a:Ck̩kЋ ?#=Gj?Wp)LĽ}4!@[e}‹k qx裼pC# F{E,eVA4Et;蘌D up8.ts]'@ve{uҤACXyn ( 76)Tک)L7F T^5 tMxno_S^+[q?~N{T!s僰,q0 mF)@,s:rfǐkxRZaG{1fsaE2s طHEԘ} G=~=߼kF<ք(^J,*>Ec&Ӡ2|Q3E]=N J5e.g!LdiEE[Zoû4SјLsM?Sab 0rؠ5o.VU6"EN*B `#2an)5 'шSNۣL ໺>B렲 _d cR94Ohg.6 W&qʴIR%rHe@ 5""Ѱ,落>[F4)@^y$F`hA'C+T'p9qLT];Ib +ԲNP K)_.O7N1FD<A3N 觿[EVt /]Ůr7'V:`{>7㴓nz1w &o`xs+>HI0 ?>HؼSx>OA y^7;p.䞠㑴Z a<8Й[EkSV(0vHquיZKZX ώ6"Mhu ,K[j_/>8/QJ Z\N{L 4,轠!^W(&+{Ő)0 @)c-p}ET{L# 0:vm#I$%"2Fe\-+_Jdh\ rT4%F4{['4ac)鬗䦅J<L^ vZ`t218qVTbku5]e2g$Br3Ae/,_qûZb-3k/}=\TEzm|b2Ɖ<ۨ<ɮgmݜKE*ܥ\kxmĊ*ard(g2zN,`AV[ ԝVk]YU?~3oO/[ do rң+U8•gCcE9eG9w$ j$UH};lH>Xf~)}x ?#<2rv~Bb )~Ԅ]Y'YNϧͬ@L}:<*~@VKqh #O QK1ikE-x'M'1+سiA"Ըl|w)Iӥ5>v.1!3`#! %PĀaSy/$+ugx]mze*e"`1Jl>3=^>lJrn װ}buKQu~ @g;K $R'g(۟'_g )efxqQeڎ/xH+'"_0&Ft|Ck9WّQfQddJ)#UH:F"!%#g""3tP䗎;s]N GHoYaŬi_*6l]$\Hոtt46Rx''Ik-ETBuB/%d=ْmמsOsG%-]O!"6`Z0izA:,z4aZ|Za?")BW޻a&yravgVmsiOOEՍƳ;wLyI sFHij\yy ќHnP|ixQm+ٵlڿfIu"pɭs])D%+%5vG1葓SJYoֿ) +l9ymS$)!P `/MG{;?aTWgߗ)]k~&6/ F{=Q~ qm7i#;>Pw䀽EJ;an*oХ0͏&:[ lQ]\#^JIa8-Q5O#`R925G_.']J#ī;OE }9l{Ln_LWH4I9nSE=GmHh-bB:TU@)冻QNR?QtТnu|.#,Tos'#o%hӯpyV0}&8矷?|/ 1*l#𜡸be7tbPQ>U"'d0<]xzogMJ[a-;J*!)AHN':FiL7˲U\c=j>ngvjMFGՏƍɣaH5@ڽI^Xoisu3V>Kv_Rʰx/{P|yy$kt}tu,.r˚rM1 3Pγu!j0}n߫mཋvtʑwWw3݋ 6Cɰ`;yn(ٱG/ja{\xpjT7Ҽ e6eE 2ёVV}s1.CXs( /TcxM'gspd2h)H4dc>>%.&tþ9=?{k]Wy-f^U&qL$H< vla a,'I[({3;q,KgQ f|tifU}_q;(4*0`;y;OR4cg9b'{{xFPKSYkG&TWB%د|Ϗد"2z{C+Rm(,MSOLB[j|7̴)tD{ ל9R=(ꂌcIg,^rT.e9D挳l)S \zÞ2I9+w\A Љ zw+]Xqx3*m2OF7 QKM 9g\`P"`Mm2fᾙpt~xY2  sИcO?9|G9y;siwSVUa14 c](;Z-!MԢ[AMf86mws:c0.K[tSNYnq/ ItLb8=1i64aÖH5W^8ZD'0BǷ =>=W㝺`>bg=Fjbc9*Fz%EZ˘kɹXtfK^̚acv*H7u~O*EQcc0mBς}ʟJkuO.@Bשm֐f[? xs!=` j8jş߮[5i>94v( bz'$: :%`2ꝅXd/3e1_ոlF"ᥬy~w~b[e4 Tſ\O{rq"S协U- 0wlw#o0Wf@հ@+Yw(4s;k[MhGai8NyE7lB]B^^˩cZVhr "ܯ#V$r0lbjcuq"Kңdm:Ɋ=Q6ܭ Mu3{}GSqGDމWٻn6YIɞiQ2BH-ٲKvo']{<{9}s|xo-@*/,2_~-SwpQ]TI~ ZTtX8E[;xvY@4KS$ܦ lN!Cʎǥ4jR,^0bv1פב~C4RMcCىx$2苪o9HlA 9Hfe-v[)Ҍ'i.e#З1UkMLKTP`LV}O&b8:rƂŸSD2 I| C eK*aq^?,Fca"Sn -2skа6-CRbUUG+ WJv$/t¬톔. =ұ{$.L4N![a ~Fխ B|& 'SflS;Ŧb|$x~|f03?^M Pg:aԋq7Ӎ9p霫٫ M7"&f'~ #ޙyq#Hww;s?'`UpZnН]qGx^ia%1&ցD]x@ FTq>{QP Τ%gċ" hx0)RVA15;id!3՜Z`eʀ9=W)vy H[1*ܨCzPE.; F.d+0ƕbJ edyYZ<ׅ/-+7 nCu֬XO0pE{[aÊS +OAʮ v;`[tspi5y*1)gM')(>zk R&+1Ed ~Q,OόO fEq&e eǟ$G?;BK*mtϹ9<_5mnT(!K6XY_*YԦH.Shu(})ˢ M쨼hfȩILiZ'rR p]Zx’D 锵gM+)CsM\_"uI}.8qd`x)E@q< lj5RBW[*߇A1݇z ޝFvd#!m }eu$EL+,^flpL;oPU֑n[Y2l'%TU8QgnDNYsؼq{D7EݳQo$ղ[FٜCp{8s4OU-,YQpHZ dJƌV,No쮧>Vem;$9 "7"s1NmV(ʸ:~:5K ̔sU=ەܞܙ,*6 cpo ?zjir7["׵dkbWp;S]Jp?:Tſ.;_?xx5ڬǕiDevUɣ<]X3,IKU*὇=U〖P=9٣f1 xYcuI ř9 TAs~QmLT`VY'MlܧL"d0 7񨂔qcFhh ό@*OEBaɬ9*8NZ$Ї7 @Ù|u45O01`P浫<>H5`H0ڪnԯ}5_¶a5?<m_pihdٻ74E" 3 ]6oOfDlvrQm3ʻyJbpEd;MAF2:Pw2؀e{?^ .8 Wh?rz8XBCXܥ1A-٪wl ވ0n47/j/$FLbB#4hh=74O7Wa7 I&>k"Dhϊ!Ry)%r6bcSlEAw=Ctu1z.Ydc?06+GD{J3w//MkA3 ϸFQٙܞn"%Χ@n9a55y-{xŴ^k\gV%r]fm)N.} n|#:`[f6 Z9h8TWЎ_K=iRTEbWJVu\vwlpDz`#ApOhhdwbg[>&@0XR&_!OV anNz!羆VKc wRD#xۅ1t=3Ӊ@_YSmBϊ +J%̑8rbٖTknK޴޼c!?Hʫr4$)X`9oғ2[ɫ%, W6s&pfjp|4zh_Ê_zw6 u'8uGaοWoZ rt_ku-dxR'ڥ*pWg|4*kIK`}bHNx͈sfwVu휿v5wz/KY{zDкv5G~kjM:AI#Å|ٲ7ʢӐ,d'$/kjtY^.y%?a/qu4 e^V$!4Ǫ{$2S &5%33Jaa815T-D$b zCfSe\nDP:)8CQ)2_1=v4XMH8'$V#̂m,cvP9.nQ!_ӟѿPYr+MQMNu+'񰌉LUㇼtLWKZ֌="1>JsA<=u9Aﱤ+UdG|VO;8vJ\dNv]L6`gI8 4a#еn9'42ےE+|,+\iTtگoU\kpwHbh?v? aBʇ(g ?U(k0lS= !|KФژDGqc INI, \؍~ &XٳeZU_o)G6鷢j!zct[)3+3 IppEj L<Cj,f(?Q)}%qJd*qzvۛ.dLUKRfh4u%@mz-K=e{{{M1zƠd>A!VJP`Rܨ<!imcRC+Sl6ISHIBgT|lʾO\'$Pn&z됢v^Pfp+=PYQj$NҐ~\mH,DO(*ܥt,^P{ܨsx6$LU7G.|hR[]h)gƟ8`~tQ|Q@V-Iu_YuJdfϧNpeP`/Pz8۰0znS-!e8 T vH &]4.µ-q7xtz2# ez'_s|0[0nxe>V8ڑXV5 ~C"7\gW5&P;*㗛 ~ 1%8) 9y'{{@߾M':[1F a&g=r(Z%;UrA6ݢz܁ԟ9P~\?Y-O׉&LE,FzwyʼnjflxCʚ˴~+Rv~QQX~2VX6U.$%6T{e2u REBg AjcHj2l'4s#ڦ,WL%>"g[{$Qb(L  :iG݆t<0ɝrXܚJI32OCOZ* _Z4IW *2Rڻ(q1t xM|3oH~)F//ļ ,OYE5kbd"cƎS'{> U!)3i;pFR\?3yvxtO}LOt f"]W7;f>6AY~MM٨SRX\yd.w4`yHqyؔ6Ϻ 0rI32R]KYQT:2/IqyH[ljʁkz5sj MI)rtY֝z->M7rfO%*t˄G=gG oeV5GaFCrML86!-R{òP@4M8*FaIf%.cX1%·UL1JDd(K݈Nhha]0c8-mO9 ]Rr9cS8H=IرS^MD>r."Njkj5߇31Z=ij5=j<f bjXu6\͌ر9[\Ab$"}Hڙ;HLzUgo4 RWـ囆Wy!7lNJ&X7s]7%6mESp=qXAsJ2:&Û.zMe=T=S7O9R47n I\}OUԷ VT'|F,ph^ ٚJ`D1|Z\$_dŢ= 빂>H;!EKhoBd. XY[8syHfCx{\v" L7O OΒqzeav-Ya8ZOM-֨"7I_ m~ǷK QC܏hcy6b>,Gf"hZjh \į 3Qz\\OtB*1 KXVȖfs{?/Jv=Ϲ=g_jr|D҈gr,'kgk` 7 {m 뛹F \1/y^㷖<^Lˡ{,ְ{7?Z|;ٌaՓAf kN‹ f61Eygwez.VOo6"9Cl9{KphQRe1DV +;}ry1}~% \`Ktl`xY/N.7 kT| ! N.d`,mxUjO{y$zb7nq 7ل֗Bw厏˲;G_åXY';ld{N'.T V<BvN`CPohl͠N!4s}f~?$|svĻ&0[bp6kz<ǯɃr<) "liIqVoi-eZVSc5p8jNdiMjbOK$e>(q˜@z(lx{ݛ52K2:$AbD2feT댁ɨf2©M.[x x9.út+%",͉ReIa:}RmyE}9e<\b[67e\ S[(8k5 x%A~FQwS6i1:P:R p5򯞊Ƹ((,0 ~w4d]^SQL'9A3mC:j1 wo`5&Ta i`$`8Bh@^w=,$5AiXyw?^7R,zw( -M$\'MeBɹck}C|͒J2X ?>] 9OaGa6;爟r6±XL a#f C\k61Mzro [D|s0Ӫ `ӣzf,ѶPEV ]Uf1eO;4+g5v,'hmR+Y]J?we/">̠Pd!``Wh<٫gce]H,/1Hn"Ko.xRxXp ,I5>H1VVcDȂ6r^0"Ivј`Ғa?/Yn^_KT hx}}7wkf[k_сS{26.!ODgxMV cY~o/.3u{/=Gt&d bWܫ^\dbwo;ʨm (BEeK h/ ~c nPQ̓ /vwAdxttB^.j,h & EK%})G|<|A(9}?qރʏ:Pu7q#V vzDBǥս&gI/kSs'Oh@}Tw@B}nl48J3""[ /4TLϊE6N$lብ0gFqA =-`Ӕz]!=wYB'o鸾waN0^. ߆~~L+L_5ՙNe?/m0کg'g}5|ǽrL|UV $+z*{f/C ;a\fK@&Cg_ (N|Bye(Lly2n2Rv}O8N8EkaMW$9!M8T|aFTEt%6t3DxYO\g^ْp>67:U?mG"9נ<3K'SAsZ *'mf# :luh9Y"G^snjq ErujawDNu~HGX-,AeX,- k9T?ӻq%7y_a¶0P;&B&#AFS:cy uoDβ#]͵z#Q9/ºjFFUͩk dqѸYL8KRy!}էpiKRȭcrŅ~LnnQiNWj7"7 -[+ .^> B_uFkL Tg$7z -3K"x`zj53.JB2:- ͺڥe q)O5 o1F9}y%d)%inkߊoWXxuhSUZάf 58>LECA d $ 'm]Le ; , [F]nD\#h3sq;oob%ߌxkJ9w԰/"[}3ruyjk8q *2Q9IJ3Vg4毣/Sv0Z&H:M49DPAqϊak9ί(Zejh+ZUm#9 MOkI7۬QUk]"ET%WQꝻr=>è(vNYƔw [Ϲ ̅ɪ [u1 oFM 6ƌ|n$nסjb3sxh3nX(½g3 (ֺ|#5 ~?75\,'edyhJ(>W^79EȄsĖb﹇ \wZ󮷉dehnU#oxL{+&ߦx>2)j+omLofD>dUwXG^΢ {f؆Wٴ3tgembZ[B۩L?Kֺ6Ux6t^;+X!MoD_P~5 Sd9GQIʙO$ìMN,>UX-ݚ} 2y&2@PRX(z{.p\ >WmiI%\U{_K-c*eZ$^\s[y 6lR.LsN):nA9f{_"g|;tKDplF^I b\ Y_U$u"OPiL޹ r`V7^C.W>y4o tisd:Tg;žnü!]u[v"_!hI|;]XRȕMbw.<ሃ| W&]؃Ǝ!hq|b- `2E3"zY5cl/"[Z>`9lVU|e[!`;d!4yy-Vk},UikY#ʩBFyШ~ kdҿۄ/<2YHΤe?vns[AV.(Gټ/:!S#\a4n|; F&q0$ȾG08(4hDiMIKx}9:Y[psJպ';/;~ @9\ӗܗ%^phxP?<}9I Aq~՜Pl ӭ֜z("y2:xTǤyuW:'&Z6pY\[K&IQ9̶lm' ^ZXz RL6_JP~fХQ̇{Z9Hp{ZhesQUuZc @ ĶUC DՄ`z pu.#~pwcؑ+nx缳erd'ocRUGI'519 VW}9mNH䠠qi!Ʊ[в ֔ dTtHv@HHjȡ0ΖO"↚:b7/D&*܏ƭs4 x _t!C _e.O-,y+v074LoQ@'TX{hU&z%m/= x$ۘIIz֋JJG<^QfCj{UDOpxۖ>r%>zHOKMvE. )j@~3Nf;hz2i@Z&[Ѯ63oGgzwzhH;Mv,im7迠wʡ+,#_nԐm$yh{] W3+^ߞOeX#_ux?KՙVdc5ܼʶ|q>c_KA;,4C`N@ F"h`3Y&eYERK`Y/R% Ҋajwlh[vH( Shf֊1k,U%RkATNg[$8Ox Y2z." l#];x4+wFE|߿m?w.z=R6%IEBjGyG~ ȽIpg}]h51g]Dq'ƚ3|Mj#I>IRmeD)ZHNχunN}:]c@>Z`xPԄb;nch=9XۓR3-tGTVoUꌁqfmZhlWAD1yP)~",+Rh /gNJUU d!{"_'#qޟsUYPJׇJ;uwj75Q|ˎՠ5 [C?q/w>ziD z*KǨʹf\爦wY0>|0~{)ϣsc.TOm61$u:!A1 cJxt)Kq%8QXuܚ1'}B#Ꭼͣ=1*A0|`V@[CsJUY^?Vj(E gUP]}t7+]ĻoǍ"Z)eq5GsC֨co2nM̆`yv5 4h1~'hf1wq?BfesbWgӨ=ꑍGyk*F;Tzϋ_J 9\un? B<ݞXZҲoM}5y<,G4;n Tp!<> ,{C/XCF >fxeu܆r,koݴYgaC\~u.JM,/Щ) I E z& `Q0 F(` epar2cmdline-0.4/pretest0000755000000000000000000000110607664453171010633 #!/bin/sh rm -f test*.log rm -rf testdir mkdir testdir && cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 gunzip -c ../$srcdir/testdata.tar.gz | tar xf - || { echo "ERROR: Could not extra test files" ; exit 1; } >&2 cp test-0.data test-0.data.orig cp test-1.data test-1.data.orig cp test-2.data test-2.data.orig cp test-3.data test-3.data.orig cp test-4.data test-4.data.orig cp test-5.data test-5.data.orig cp test-6.data test-6.data.orig cp test-7.data test-7.data.orig cp test-8.data test-8.data.orig cp test-9.data test-9.data.orig exit 77; par2cmdline-0.4/test10000755000000000000000000000053507664453174010215 #!/bin/sh cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 banner="Verifying using PAR 1.0 data" dashes=`echo "$banner" | sed s/./-/g` echo $dashes echo $banner echo $dashes ../par2 v testdata.par > ../test1.log || { echo "ERROR: Initial PAR 1.0 verification failed" ; exit 1; } >&2 rm -f ../test1.log exit 0; par2cmdline-0.4/test20000755000000000000000000000053607664453174010217 #!/bin/sh cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 banner="Verifying using PAR 2.0 data" dashes=`echo "$banner" | sed s/./-/g` echo $dashes echo $banner echo $dashes ../par2 v testdata.par2 > ../test2.log || { echo "ERROR: Initial PAR 2.0 verification failed" ; exit 1; } >&2 rm -f ../test2.log exit 0; par2cmdline-0.4/test30000755000000000000000000000104607664453174010215 #!/bin/sh cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 banner="Repairing two files using PAR 1.0 data" dashes=`echo "$banner" | sed s/./-/g` echo $dashes echo $banner echo $dashes rm -f test-1.data test-3.data ../par2 r testdata.par > ../test3.log || { echo "ERROR: Reconstruction of two files using PAR 1.0 failed" ; exit 1; } >&2 cmp -s test-1.data test-1.data.orig && cmp -s test-3.data test-3.data.orig || { echo "ERROR: Repaired files do not match originals" ; exit 1; } >&2 rm -f ../test3.log exit 0; par2cmdline-0.4/test40000755000000000000000000000104707664453174010217 #!/bin/sh cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 banner="Repairing two files using PAR 2.0 data" dashes=`echo "$banner" | sed s/./-/g` echo $dashes echo $banner echo $dashes rm -f test-1.data test-3.data ../par2 r testdata.par2 > ../test4.log || { echo "ERROR: Reconstruction of two files using PAR 2.0 failed" ; exit 1; } >&2 cmp -s test-1.data test-1.data.orig && cmp -s test-3.data test-3.data.orig || { echo "ERROR: Repaired files do not match originals" ; exit 1; } >&2 rm -f ../test4.log exit 0; par2cmdline-0.4/test50000755000000000000000000000056007664453174010217 #!/bin/sh cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 banner="Creating 100% PAR 2.0 recovery data" dashes=`echo "$banner" | sed s/./-/g` echo $dashes echo $banner echo $dashes ../par2 c -r100 -b190 newtest test-*.data > ../test5.log || { echo "ERROR: Creating PAR 2.0 data failed" ; exit 1; } >&2 rm -f ../test5.log exit 0; par2cmdline-0.4/test60000755000000000000000000000150007664453174010213 #!/bin/sh cd testdir || { echo "ERROR: Could not change to test directory" ; exit 1; } >&2 banner="Repairing 100% loss using PAR 2.0 data" dashes=`echo "$banner" | sed s/./-/g` echo $dashes echo $banner echo $dashes rm -f test-*.data ../par2 r newtest > ../test6.log || { echo "ERROR: Full Repair using PAR 2.0 failed" ; exit 1; } >&2 cmp -s test-0.data test-0.data.orig && cmp -s test-1.data test-1.data.orig && cmp -s test-2.data test-2.data.orig && cmp -s test-3.data test-3.data.orig && cmp -s test-4.data test-4.data.orig && cmp -s test-5.data test-5.data.orig && cmp -s test-6.data test-6.data.orig && cmp -s test-7.data test-7.data.orig && cmp -s test-8.data test-8.data.orig && cmp -s test-9.data test-9.data.orig || { echo "ERROR: Repaired files do not match originals" ; exit 1 ; } >&2 rm -f ../test6.log exit 0; par2cmdline-0.4/posttest0000755000000000000000000000004507664453171011033 #!/bin/sh rm -rf testdir exit 77;