Index: /trunk/soft/ObsData/MANIFEST
===================================================================
--- /trunk/soft/ObsData/MANIFEST	(revision 156)
+++ /trunk/soft/ObsData/MANIFEST	(revision 157)
@@ -11,4 +11,5 @@
 ObsData/Archive/Tar.pm
 ObsData/Archive/Zip.pm
+ObsData/Archive/Rar.pm
 testdata/coin
 testdata/coin.gz
@@ -16,4 +17,5 @@
 testdata/coin.tar.gz
 testdata/coin.zip
+testdata/coin.rar
 testdata/obsdata-conftest
 testdata/obsdata-wrongconf
Index: /trunk/soft/ObsData/NEWS
===================================================================
--- /trunk/soft/ObsData/NEWS	(revision 156)
+++ /trunk/soft/ObsData/NEWS	(revision 157)
@@ -3,5 +3,5 @@
 o 0.2.0
   - add --dry-run, aka said all but does nothing !
-  - add Zip file support
+  - add Zip and Rar file support
 
 o 0.1
Index: /trunk/soft/ObsData/ObsData/Archive.pm
===================================================================
--- /trunk/soft/ObsData/ObsData/Archive.pm	(revision 156)
+++ /trunk/soft/ObsData/ObsData/Archive.pm	(revision 157)
@@ -10,4 +10,5 @@
 use ObsData::Archive::Tar;
 use ObsData::Archive::Zip;
+use ObsData::Archive::Rar;
 
 our $CVSID = q$Id$;
@@ -46,4 +47,8 @@
         /\.zip$/ and do {
             $beclass = 'Zip';
+            last;
+        };
+        /\.rar$/ and do {
+            $beclass = 'Rar';
             last;
         };
Index: /trunk/soft/ObsData/ObsData/Archive/Rar.pm
===================================================================
--- /trunk/soft/ObsData/ObsData/Archive/Rar.pm	(revision 157)
+++ /trunk/soft/ObsData/ObsData/Archive/Rar.pm	(revision 157)
@@ -0,0 +1,76 @@
+# $Id$
+
+package ObsData::Archive::Rar;
+
+use strict;
+use warnings;
+use File::Copy;
+use File::Temp qw/ tempfile tempdir /;
+use Cwd;
+
+our @ISA = qw(ObsData::Archive);
+
+sub new {
+    my ($class, $options) = @_;
+    bless($options, $class);
+}
+
+sub DESTROY_ {
+    my ($self) = @_;
+}
+
+sub ls {
+    my ($self) = @_;
+    open(my $hrar, '-|', "unrar lb '$self->{archive}'") or do {
+        $self->seterror("Can't read zip file: $!");
+        return undef;
+    };
+    my @list;
+    while(<$hrar>) {
+        chomp;
+        push(@list, $_);
+    }
+    close($hrar);
+    return @list;
+}
+
+sub extract {
+    my ($self, $file, $dest) = @_;
+
+    my ($fh, $fname);
+    
+    if ($dest) {
+        $fname = $dest;
+        open($fh, '>', $dest) or do {
+            $self->seterror("Can't uncompress archive: $!");
+            return undef;
+        };
+    } else {
+        ($fh, $fname) = tempfile(
+            DIR => $self->_tempdir,
+            UNLINK => 1,
+        ) or do {
+            $self->seterror("Can't create temp file: $!");
+            return undef;
+        };
+    }
+
+    open(my $sourcefh, "unrar p -ierr '$self->{archive}' '$file' 2>/dev/null |") or return undef;
+    
+    if(!copy($sourcefh, $fh)) {
+        $self->seterror("Can't copy file to destination: $!");
+        unlink($fname);
+        return undef;
+    }
+    
+    close($fh);
+    # FIXME unrar sucks, does return a proper exit status on error (allways 0)
+    if(!close($sourcefh)) {
+        $self->seterror("unrar -p exit with error" . ($! ? (" " . $!) : ""));
+        unlink($fname);
+        return undef;
+    }
+    $fname
+}
+
+1;
Index: /trunk/soft/ObsData/t/OA-01.t
===================================================================
--- /trunk/soft/ObsData/t/OA-01.t	(revision 156)
+++ /trunk/soft/ObsData/t/OA-01.t	(revision 157)
@@ -1,5 +1,5 @@
 # $Id$
 
-use Test::More tests => 10;
+use Test::More tests => 12;
 
 foreach (qw(
@@ -8,4 +8,5 @@
         ObsData::Archive::Tar
         ObsData::Archive::Zip
+        ObsData::Archive::Rar
         )) {
     use_ok($_);
Index: /trunk/soft/ObsData/t/OA-06.t
===================================================================
--- /trunk/soft/ObsData/t/OA-06.t	(revision 157)
+++ /trunk/soft/ObsData/t/OA-06.t	(revision 157)
@@ -0,0 +1,19 @@
+# $Id$
+
+use Test::More tests => 4;
+use ObsData::Archive;
+use File::Temp qw(tempdir);
+
+my $tempdir = tempdir;
+print $tempdir . "\n";
+
+my $oa = ObsData::Archive->new('testdata/coin.rar');
+
+isa_ok($oa, 'ObsData::Archive::Rar');
+my ($list) = $oa->ls();
+ok($list eq 'coin', "Can list its contents");
+
+ok($oa->extract('coin', "$tempdir/coin"), "Can extract the file");
+ok(-r "$tempdir/coin", "the file has been really extract");
+
+system(qw(rm -fr), $tempdir);
