summaryrefslogtreecommitdiff
path: root/misc/par2cmdline
diff options
context:
space:
mode:
Diffstat (limited to 'misc/par2cmdline')
-rw-r--r--misc/par2cmdline/README10
-rw-r--r--misc/par2cmdline/par2.1284
-rw-r--r--misc/par2cmdline/par2cmdline.SlackBuild96
-rw-r--r--misc/par2cmdline/par2cmdline.info10
-rw-r--r--misc/par2cmdline/patches/gcc4.patch62
-rw-r--r--misc/par2cmdline/patches/letype.patch219
-rw-r--r--misc/par2cmdline/patches/offset.patch16
-rw-r--r--misc/par2cmdline/patches/precedence.patch108
-rw-r--r--misc/par2cmdline/slack-desc19
9 files changed, 824 insertions, 0 deletions
diff --git a/misc/par2cmdline/README b/misc/par2cmdline/README
new file mode 100644
index 0000000000..2e1f55e960
--- /dev/null
+++ b/misc/par2cmdline/README
@@ -0,0 +1,10 @@
+par2cmdline (Commandline implementation of PARv2.0 specification)
+
+par2cmdline is a GPL-licensed commandline tool for creating and using PAR2
+parity sets to detect damage in files and repair them if necessary. The
+program uses Reed Solomon Coding to perform its error correction. A useful
+program for checking and ensuring the integrity of binaries retrieved from
+usenet for instance.
+
+Several patches have been included to fix compilation issues on current
+platforms.
diff --git a/misc/par2cmdline/par2.1 b/misc/par2cmdline/par2.1
new file mode 100644
index 0000000000..b10f5e7f09
--- /dev/null
+++ b/misc/par2cmdline/par2.1
@@ -0,0 +1,284 @@
+.\"
+.\" par2(1)
+.\"
+.\" Copyright (C) 2004 Andres Salomon
+.TH par2 1 "May 2004"
+.SH NAME
+par2 \- PAR 2.0 compatible file verification and repair tool.
+.SH SYNOPSIS
+.B par2
+c(reate) [options] <par2 file> [files]
+.br
+.B par2
+v(erify) [options] <par2 file> [files]
+.br
+.B par2
+r(epair) [options] <par2 file> [files]
+.br
+
+.br
+ Or:
+.br
+
+.br
+.B par2create
+[options] <par2 file> [files]
+.br
+.B par2verify
+[options] <par2 file> [files]
+.br
+.B par2repair
+[options] <par2 file> [files]
+.SH DESCRIPTION
+par2 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.
+.SH OPTIONS
+.TP
+.B -b<n>
+Set the Block-Count
+.TP
+.B -s<n>
+Set the Block-Size (Don't use both -b and -s)
+.TP
+.B -r<n>
+Level of Redundancy (%)
+.TP
+.B -c<n>
+Recovery block count (don't use both -r and -c)
+.TP
+.B -f<n>
+First Recovery-Block-Number
+.TP
+.B -u
+Uniform recovery file sizes
+.TP
+.B -l
+Limit size of recovery files (Don't use both -u and -l)
+.TP
+.B -n<n>
+Number of recovery files (Don't use both -n and -l)
+.TP
+.B -m<n>
+Memory (in MB) to use
+.TP
+.B -v [-v]
+Be more verbose
+.TP
+.B -q [-q]
+Be more quiet (-qq gives silence)
+.TP
+.B --
+Treat all remaining CommandLine as filenames
+.TP
+.BR
+.SH EXAMPLES
+
+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 par2 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 par2.
+
+e.g.:
+
+ par2 verify test.mpg.par2
+
+This tells par2 to use the information in test.mpg.par2 to verify the
+data files.
+
+par2 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 par2 will report that repair
+will not be required.
+
+If any of the data files are missing or damaged, par2 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 par2 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
+par2 will not automatically find and scan them.
+
+To have par2 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 par2 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 par2 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 par2 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 par2 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 par2 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 par2 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).
+
+.SH NOTES
+
+This version of par2 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.
+
+.SH 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''
+<http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.html>
+
+.SH AUTHOR
+.br
+.B par2
+was written by Peter Brian Clements <peterbclements@users.sourceforge.net>.
+
+This man page was contributed by Andres Salomon <dilinger@voxel.net>
+for the Debian GNU/Linux system (but may be used by others).
diff --git a/misc/par2cmdline/par2cmdline.SlackBuild b/misc/par2cmdline/par2cmdline.SlackBuild
new file mode 100644
index 0000000000..c8a6de276e
--- /dev/null
+++ b/misc/par2cmdline/par2cmdline.SlackBuild
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# Slackware build script for par2cmdline
+# Written by Thomas Morper <thomas@beingboiled.info>
+# Thanks to maldoror for the previous version of this script
+# Thanks to Debian, Fedora and Gentoo for patches and the man page
+
+PRGNAM=par2cmdline
+VERSION=${VERSION:-0.4}
+ARCH=${ARCH:-i486}
+BUILD=${BUILD:-1}
+TAG=${TAG:-_SBo}
+
+CWD=$(pwd)
+TMP=${TMP:-/tmp/SBo}
+PKG=$TMP/package-$PRGNAM
+OUTPUT=${OUTPUT:-/tmp}
+
+if [ "$ARCH" = "i486" ]; then
+ SLKCFLAGS="-O2 -march=i486 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=i686 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -fPIC"
+ LIBDIRSUFFIX="64"
+fi
+
+set -e
+
+rm -rf $PKG
+mkdir -p $TMP $PKG $OUTPUT
+cd $TMP
+rm -rf $PRGNAM-$VERSION
+tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
+cd $PRGNAM-$VERSION
+chown -R root:root .
+find . \
+ \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \
+ -exec chmod 755 {} \; -o \
+ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
+ -exec chmod 644 {} \;
+
+# Fix wrong permissions
+chmod 644 ChangeLog NEWS
+
+# Make it work with gcc4
+patch -p1 < $CWD/patches/gcc4.patch
+
+# Fix crash in quiet mode
+patch -p1 < $CWD/patches/offset.patch
+
+# Kill warnings (and fix a PPC compilation error)
+patch -p1 < $CWD/patches/letype.patch
+
+# Kill warnings
+patch -p1 < $CWD/patches/precedence.patch
+
+CFLAGS="$SLKCFLAGS" \
+CXXFLAGS="$SLKCFLAGS" \
+./configure \
+ --prefix=/usr \
+ --libdir=/usr/lib${LIBDIRSUFFIX} \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --build=$ARCH-slackware-linux
+
+make
+make check
+make install-strip DESTDIR=$PKG
+
+mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
+cp -a AUTHORS COPYING ChangeLog INSTALL NEWS PORTING README ROADMAP \
+ $PKG/usr/doc/$PRGNAM-$VERSION
+cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
+
+# Replace the hardlinks with symlinks
+cd $PKG/usr/bin
+rm -f par2create; ln -s par2 par2create
+rm -f par2repair; ln -s par2 par2repair
+rm -f par2verify; ln -s par2 par2verify
+
+# Install the man pages
+mkdir -p $PKG/usr/man/man1
+gzip -9 < $CWD/par2.1 > $PKG/usr/man/man1/par2.1.gz
+cd $PKG/usr/man/man1
+ln -s par2.1.gz par2create.1.gz
+ln -s par2.1.gz par2repair.1.gz
+ln -s par2.1.gz par2verify.1.gz
+
+mkdir -p $PKG/install
+cat $CWD/slack-desc > $PKG/install/slack-desc
+
+cd $PKG
+/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}
diff --git a/misc/par2cmdline/par2cmdline.info b/misc/par2cmdline/par2cmdline.info
new file mode 100644
index 0000000000..5c681b79bd
--- /dev/null
+++ b/misc/par2cmdline/par2cmdline.info
@@ -0,0 +1,10 @@
+PRGNAM="par2cmdline"
+VERSION="0.4"
+HOMEPAGE="http://parchive.sourceforge.net"
+DOWNLOAD="http://downloads.sourceforge.net/parchive/par2cmdline-0.4.tar.gz"
+MD5SUM="1551b63e57e3c232254dc62073b723a9"
+DOWNLOAD_x86_64=""
+MD5SUM_x86_64=""
+MAINTAINER="Thomas Morper"
+EMAIL="thomas@beingboiled.info"
+APPROVED="Erik Hanson"
diff --git a/misc/par2cmdline/patches/gcc4.patch b/misc/par2cmdline/patches/gcc4.patch
new file mode 100644
index 0000000000..c6da26789e
--- /dev/null
+++ b/misc/par2cmdline/patches/gcc4.patch
@@ -0,0 +1,62 @@
+Fix compilation with gcc-4.
+
+Patch by Dirk-Jan Heijs.
+
+http://bugs.gentoo.org/102391
+http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=287904
+
+--- par2cmdline-0.4/reedsolomon.cpp
++++ par2cmdline-0.4/reedsolomon.cpp
+@@ -51,7 +51,7 @@
+ }
+ }
+
+-bool ReedSolomon<Galois8>::SetInput(const vector<bool> &present)
++template <> bool ReedSolomon<Galois8>::SetInput(const vector<bool> &present)
+ {
+ inputcount = (u32)present.size();
+
+@@ -80,7 +80,7 @@
+ return true;
+ }
+
+-bool ReedSolomon<Galois8>::SetInput(u32 count)
++template <> bool ReedSolomon<Galois8>::SetInput(u32 count)
+ {
+ inputcount = count;
+
+@@ -101,7 +101,7 @@
+ return true;
+ }
+
+-bool ReedSolomon<Galois8>::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer)
++template <> bool ReedSolomon<Galois8>::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];
+@@ -189,7 +189,7 @@
+
+ // 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<Galois16>::SetInput(const vector<bool> &present)
++template <> bool ReedSolomon<Galois16>::SetInput(const vector<bool> &present)
+ {
+ inputcount = (u32)present.size();
+
+@@ -233,7 +233,7 @@
+
+ // Record that the specified number of source files are all present
+ // and compute the base values to use for the vandermonde matrix.
+-bool ReedSolomon<Galois16>::SetInput(u32 count)
++template <> bool ReedSolomon<Galois16>::SetInput(u32 count)
+ {
+ inputcount = count;
+
+@@ -267,7 +267,7 @@
+ return true;
+ }
+
+-bool ReedSolomon<Galois16>::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer)
++template <> bool ReedSolomon<Galois16>::Process(size_t size, u32 inputindex, const void *inputbuffer, u32 outputindex, void *outputbuffer)
+ {
+ // Look up the appropriate element in the RS matrix
diff --git a/misc/par2cmdline/patches/letype.patch b/misc/par2cmdline/patches/letype.patch
new file mode 100644
index 0000000000..e0c8d6c57b
--- /dev/null
+++ b/misc/par2cmdline/patches/letype.patch
@@ -0,0 +1,219 @@
+diff -ur par2cmdline-0.4-orig/letype.h par2cmdline-0.4/letype.h
+--- par2cmdline-0.4-orig/letype.h 2003-05-26 20:01:17.000000000 +0200
++++ par2cmdline-0.4/letype.h 2006-05-09 10:47:29.000000000 +0200
+@@ -28,44 +28,15 @@
+
+ #else
+
+-class leu16
++struct 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);
+@@ -81,46 +52,15 @@
+ }
+
+
+-class leu32
++struct 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);
+@@ -140,50 +80,15 @@
+ }
+
+
+-class leu64
++struct 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);
+diff -ur par2cmdline-0.4-orig/md5.h par2cmdline-0.4/md5.h
+--- par2cmdline-0.4-orig/md5.h 2003-08-02 01:41:04.000000000 +0200
++++ par2cmdline-0.4/md5.h 2006-05-09 10:47:29.000000000 +0200
+@@ -20,6 +20,13 @@
+ #ifndef __MD5_H__
+ #define __MD5_H__
+
++#ifdef WIN32
++#pragma pack(push, 1)
++#define PACKED
++#else
++#define PACKED __attribute__ ((packed))
++#endif
++
+ // This file defines the MD5Hash and MD5Context objects which are used
+ // to compute and manipulate the MD5 Hash values for a block of data.
+
+@@ -35,12 +42,11 @@
+
+ // MD5 Hash value
+
+-class MD5Hash
+-{
+-public:
+- // Constructor does not initialise the value
+- MD5Hash(void) {};
++struct MD5Hash;
++ostream& operator<<(ostream &s, const MD5Hash &hash);
+
++struct MD5Hash
++{
+ // Comparison operators
+ bool operator==(const MD5Hash &other) const;
+ bool operator!=(const MD5Hash &other) const;
+@@ -54,13 +60,8 @@
+ 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
+-};
++} PACKED;
+
+ // Intermediate computation state
+
+@@ -144,16 +145,9 @@
+ 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;
+-}
++#ifdef WIN32
++#pragma pack(pop)
++#endif
++#undef PACKED
+
+ #endif // __MD5_H__
diff --git a/misc/par2cmdline/patches/offset.patch b/misc/par2cmdline/patches/offset.patch
new file mode 100644
index 0000000000..6539280668
--- /dev/null
+++ b/misc/par2cmdline/patches/offset.patch
@@ -0,0 +1,16 @@
+--- par2cmdline-0.4.orig/par2creatorsourcefile.cpp 2004-04-15 14:45:23.000000000 +0100
++++ par2cmdline-0.4/par2creatorsourcefile.cpp 2005-09-29 02:27:43.000000000 +0100
+@@ -213,11 +213,12 @@
+ }
+ }
+
++ offset += want;
++
+ if (noiselevel > CommandLine::nlQuiet)
+ {
+ // Display progress
+ u32 oldfraction = (u32)(1000 * offset / filesize);
+- offset += want;
+ u32 newfraction = (u32)(1000 * offset / filesize);
+ if (oldfraction != newfraction)
+ {
diff --git a/misc/par2cmdline/patches/precedence.patch b/misc/par2cmdline/patches/precedence.patch
new file mode 100644
index 0000000000..736e9f4a8e
--- /dev/null
+++ b/misc/par2cmdline/patches/precedence.patch
@@ -0,0 +1,108 @@
+This patch just adds some extra parentheses to stop the compiler from
+warning about the possible mix-up of operator precedence.
+
+diff -u -r par2cmdline-0.4-orig/par1repairer.cpp par2cmdline-0.4/par1repairer.cpp
+--- par2cmdline-0.4-orig/par1repairer.cpp 2004-04-15 15:40:48.000000000 +0200
++++ par2cmdline-0.4/par1repairer.cpp 2009-09-08 18:38:15.375114246 +0200
+@@ -324,7 +324,7 @@
+ ||
+ (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)))
++ (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
+@@ -518,9 +518,9 @@
+ // 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')
++ ((tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r'))
+ ||
+- isdigit(tail[1]) && isdigit(tail[2])
++ (isdigit(tail[1]) && isdigit(tail[2]))
+ ))
+ {
+ LoadRecoveryFile(filename);
+@@ -549,9 +549,9 @@
+ // 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')
++ ((tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r'))
+ ||
+- isdigit(tail[1]) && isdigit(tail[2])
++ (isdigit(tail[1]) && isdigit(tail[2]))
+ ))
+ {
+ LoadRecoveryFile(filename);
+@@ -652,9 +652,9 @@
+ // 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')
++ ((tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r'))
+ ||
+- isdigit(tail[1]) && isdigit(tail[2])
++ (isdigit(tail[1]) && isdigit(tail[2]))
+ ))
+ {
+ skip = true;
+diff -u -r par2cmdline-0.4-orig/verificationhashtable.h par2cmdline-0.4/verificationhashtable.h
+--- par2cmdline-0.4-orig/verificationhashtable.h 2003-06-03 13:48:52.000000000 +0200
++++ par2cmdline-0.4/verificationhashtable.h 2009-09-08 18:37:51.945290947 +0200
+@@ -66,11 +66,11 @@
+ // Comparison operators for searching
+ bool operator <(const VerificationHashEntry &r) const
+ {
+- return crc < r.crc || crc == r.crc && hash < r.hash;
++ 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;
++ return crc > r.crc || (crc == r.crc && hash > r.hash);
+ }
+ bool operator ==(const VerificationHashEntry &r) const
+ {
+@@ -183,11 +183,11 @@
+
+ while (entry)
+ {
+- if (entry->crc < crc || entry->crc == crc && entry->hash < hash)
++ if (entry->crc < crc || (entry->crc == crc && entry->hash < hash))
+ {
+ entry = entry->right;
+ }
+- else if (entry->crc > crc || entry->crc == crc && entry->hash > hash)
++ else if (entry->crc > crc || (entry->crc == crc && entry->hash > hash))
+ {
+ entry = entry->left;
+ }
+@@ -402,14 +402,14 @@
+ // 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()
++ (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()
++ (checksummer.ShortBlock() && checksummer.BlockLength() != currententry->GetDataBlock()->GetLength())
+ )
+ )
+ {
+@@ -426,7 +426,7 @@
+
+ // Check for an unused entry which is the correct length
+ while (nextentry && (nextentry->IsSet() ||
+- checksummer.ShortBlock() && checksummer.BlockLength() != nextentry->GetDataBlock()->GetLength()
++ (checksummer.ShortBlock() && checksummer.BlockLength() != nextentry->GetDataBlock()->GetLength())
+ )
+ )
+ {
diff --git a/misc/par2cmdline/slack-desc b/misc/par2cmdline/slack-desc
new file mode 100644
index 0000000000..e17c3e4174
--- /dev/null
+++ b/misc/par2cmdline/slack-desc
@@ -0,0 +1,19 @@
+# HOW TO EDIT THIS FILE:
+# The "handy ruler" below makes it easier to edit a package description. Line
+# up the first '|' above the ':' following the base package name, and the '|'
+# on the right side marks the last column you can put a character in. You must
+# make exactly 11 lines for the formatting to be correct. It's also
+# customary to leave one space after the ':'.
+
+ |-----handy-ruler------------------------------------------------------|
+par2cmdline: par2cmdline (Commandline implementation of PARv2.0 specification)
+par2cmdline:
+par2cmdline: par2cmdline is a GPL-licensed commandline tool for creating and
+par2cmdline: using PAR2 parity sets to detect damage in files and repair them
+par2cmdline: if necessary. The program uses Reed Solomon Coding to perform its
+par2cmdline: error correction. A useful program for checking and ensuring the
+par2cmdline: integrity of binaries retrieved from usenet for instance.
+par2cmdline:
+par2cmdline: http://parchive.sourceforge.net/
+par2cmdline:
+par2cmdline: