From 5d9e713cea66d1a068152b0c024c980c729bed05 Mon Sep 17 00:00:00 2001 From: tv <thierry.vignaud@gmail.com> Date: Thu, 29 Nov 2012 10:58:42 +0100 Subject: [PATCH 3/3] initial perl binding --- Makefile | 6 +++- perl/Makefile.PL | 17 ++++++++++ perl/deltarpm.pm | 59 ++++++++++++++++++++++++++++++++++ perl/deltarpm.xs | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 perl/Makefile.PL create mode 100644 perl/deltarpm.pm create mode 100644 perl/deltarpm.xs diff --git a/Makefile b/Makefile index 0d0028f..1a24809 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,10 @@ all: makedeltarpm applydeltarpm rpmdumpheader makedeltaiso applydeltaiso combine python: _deltarpmmodule.so +perl: + cd perl; perl Makefile.PL + @make -C perl + makedeltarpm: makedeltarpm.o writedeltarpm.o md5.o util.o rpml.o rpmhead.o cpio.o delta.o cfile.o $(zlibbundled) applydeltarpm: applydeltarpm.o readdeltarpm.o md5.o sha256.o util.o rpmhead.o cpio.o cfile.o prelink.o $(zlibbundled) @@ -83,7 +87,7 @@ install: fi; \ done -.PHONY: clean install +.PHONY: clean install perl makedeltarpm.o: makedeltarpm.c deltarpm.h util.h md5.h rpmhead.h delta.h cfile.h applydeltarpm.o: applydeltarpm.c deltarpm.h util.h md5.h rpmhead.h cpio.h cfile.h prelink.h diff --git a/perl/Makefile.PL b/perl/Makefile.PL new file mode 100644 index 0000000..2aa3b25 --- /dev/null +++ b/perl/Makefile.PL @@ -0,0 +1,17 @@ +use ExtUtils::MakeMaker; + +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +my $libs = "" . `pkg-config --libs liblzma`; +chomp $libs; +WriteMakefile( + 'NAME' => 'deltarpm', + 'OPTIMIZE' => '-Wno-declaration-after-statement -Wall', + 'VERSION_FROM' => 'deltarpm.pm', + 'OBJECT' => 'deltarpm.o ../readdeltarpm.o ../rpmhead.o ../util.o ../md5.o ../cfile.o', + 'LIBS' => $libs, + 'DEFINE' => '-DPACKAGE_NAME=\"deltarpm\"', + 'INC' => "-I.. `pkg-config --cflags rpm`", # -I.. for deltarpm + 'XSPROTOARG' => '-noprototypes', + 'TYPEMAPS' => [ '../perlobject.map' ], +); diff --git a/perl/deltarpm.pm b/perl/deltarpm.pm new file mode 100644 index 0000000..e7d701b --- /dev/null +++ b/perl/deltarpm.pm @@ -0,0 +1,59 @@ +package deltarpm; +# Copyright 2012 Thierry Vignaud for Mageia +# +# This program is free software; you can redistribute it and/or +# modify it under the same terms as Perl itself, or under GPL or BSD license. + + +use strict; +use warnings; +use DynaLoader; + +our @ISA = qw(DynaLoader); +our $VERSION = '0.1'; + +deltarpm->bootstrap($VERSION); + + +1; + +__END__ + +=head1 NAME + +deltarpm - Manipulate delta RPM files + +=head1 SYNOPSIS + + use deltarpm; + use Data::Dumper; + + my $d = deltarpm::read("libreoffice-writer-3.5.5.3-0.3.mga2.x86_64.drpm"); + warn Dumper $d; + +=head1 DESCRIPTION + +The deltarpm module allows you to manipulate delta RPM files. +It will be used by the C<genhdlist2> utility to generate meta-data aware of delta rpms so that L<urpmi> can perform updates with smaller deltarpms. + +=head2 Functions + +=over + +=item readDeltaRPM($filename) + +Return an hash containing information about the deltarpm file. + +=back + +=head1 COPYRIGHT + +Copyright 2012, Mageia + +Thierry Vignaud <tv@mageia.org> + +This library is free software; you can redistribute it and/or modify it under +the same terms as Perl itself. + +=cut + diff --git a/perl/deltarpm.xs b/perl/deltarpm.xs new file mode 100644 index 0000000..3a3e05d --- /dev/null +++ b/perl/deltarpm.xs @@ -0,0 +1,97 @@ +/* Copyright (c) 2012 Thierry Vignaud for Mageia + * This program is free software; you can redistribute it and/or + * modify it under the same terms as Perl itself, or under GPL or BSD license. + */ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include "cfile.h" +#include "deltarpm.h" + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> + +char *seq_to_string(unsigned int seql, unsigned char *seq) { + char *tmp = calloc(seql * 2 + 1, sizeof(char)); + int i; + for (i = 0; i < seql; i++) { + char buff[3]; + snprintf(buff, 3, "%02x", seq[i]); + strcat(tmp, buff); + } + return tmp; +} + +HV* ReadObjectFromFile(FILE *file) { + HV * rh; + + char *src_nevr, *target_nevr, *seq; + int nb; + unsigned int seql; + char buf[BUFSIZ]; + fgets(buf, BUFSIZ, file); + nb = sscanf(buf, "srcnevr=%as targetnevr=%as seql=%d, seq=%as\n", &src_nevr, &target_nevr, &seql, &seq); + if (nb != 4) + croak("unable to get deltarpm info"); + + rh = newHV(); + hv_store(rh, "src_nevr", 8, newSVpv(src_nevr, 0), 0); + hv_store(rh, "target_nevr", 11, newSVpv(target_nevr, 0), 0); + /* Sequence */ + if (seq) + hv_store(rh, "seq", 3, newSVpv(seq, 0), 0); + free(seq); + free(src_nevr); + free(target_nevr); + return rh; +} + + +MODULE = deltarpm PACKAGE = deltarpm PREFIX = delta_ + +SV* +delta_read(filename) + char *filename; + PREINIT: + struct deltarpm d; + int pid; + int ipcpipe[2]; + + CODE: + /* The delta rpm code does not expect to be used in its way. Its error handling + * consists of 'printf' and 'exit'. So, dirty hacks abound. + * Also it's leaky. + */ + if (pipe(ipcpipe) == -1) + croak("unable to create pipe"); + + if ((pid = fork())) { + FILE *readend = fdopen(ipcpipe[0], "r"); + int rc, status; + + rc = waitpid(pid, &status, 0); + if (rc == -1 || (WIFEXITED(status) && WEXITSTATUS(status) != 0)) + croak("unable to read deltarpm file %s (status=%d)", filename, status); + + + RETVAL = sv_2mortal((SV*)SvREFCNT_inc(newRV_noinc((SV *)ReadObjectFromFile(readend)))); + fclose(readend); + } else { + char *tmp; + FILE *writend = fdopen(ipcpipe[1], "w"); + + readdeltarpm(filename, &d, NULL); + if (d.seql) + tmp = seq_to_string(d.seql, d.seq); + fprintf(writend, "srcnevr=%s targetnevr=%s seql=%d, seq=%s\n", d.nevr, d.targetnevr, d.seql, + d.seql ? tmp : ""); + fclose(writend); + free(tmp); + _exit(0); + } + close(ipcpipe[1]); +OUTPUT: +RETVAL + -- 1.8.0.1