summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perl-install/c/.cvsignore7
-rw-r--r--perl-install/c/Makefile15
-rw-r--r--perl-install/c/Makefile.PL5
-rw-r--r--perl-install/c/stuff.pm29
-rw-r--r--perl-install/c/stuff.xs.pm576
5 files changed, 627 insertions, 5 deletions
diff --git a/perl-install/c/.cvsignore b/perl-install/c/.cvsignore
index 0c6427c49..8453a1ab9 100644
--- a/perl-install/c/.cvsignore
+++ b/perl-install/c/.cvsignore
@@ -1,6 +1,7 @@
Makefile
-c.c
-c.bs
+stuff.c
+stuff.bs
pm_to_blib
+Makefile_c.old
blib
-c.xs
+stuff.xs
diff --git a/perl-install/c/Makefile b/perl-install/c/Makefile
new file mode 100644
index 000000000..dcd777bb7
--- /dev/null
+++ b/perl-install/c/Makefile
@@ -0,0 +1,15 @@
+.PHONY: clean
+
+stuff: %: %.xs
+ test -e Makefile_c || C_RPM=1 perl Makefile.PL
+ $(MAKE) -f Makefile_c
+ ln -sf ../c/blib/arch/auto ../auto/c
+
+clean:
+ test ! -e Makefile_c || $(MAKE) -f Makefile_c clean
+ rm -f *~ stuff.xs
+
+stuff.xs: %: %.pm
+ rm -f $@
+ export C_RPM=1 ; perl $< > $@
+ chmod a-w $@
diff --git a/perl-install/c/Makefile.PL b/perl-install/c/Makefile.PL
index 85030d3c4..647d5bcc0 100644
--- a/perl-install/c/Makefile.PL
+++ b/perl-install/c/Makefile.PL
@@ -7,9 +7,10 @@ my $libs = '-L/usr/X11R6/lib -lX11 -lgdk';
$libs .= ' -lrpm -ldb1 -lz' if $ENV{C_RPM};
WriteMakefile(
- 'NAME' => 'c',
+ 'NAME' => 'stuff',
'OPTIMIZE' => '-Os',
- 'VERSION_FROM' => 'c.pm', # finds $VERSION
+ 'MAKEFILE' => 'Makefile_c',
+ 'VERSION_FROM' => 'stuff.pm', # finds $VERSION
'LIBS' => [$libs], # e.g., '-lm'
'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
'INC' => '-I/usr/include/rpm `gtk-config --cflags`', # e.g., '-I/usr/include/other'
diff --git a/perl-install/c/stuff.pm b/perl-install/c/stuff.pm
new file mode 100644
index 000000000..ad5cf316d
--- /dev/null
+++ b/perl-install/c/stuff.pm
@@ -0,0 +1,29 @@
+package c::stuff;
+
+use strict;
+use vars qw($VERSION @ISA);
+
+require DynaLoader;
+
+@ISA = qw(DynaLoader);
+$VERSION = '0.01';
+
+bootstrap c::stuff $VERSION;
+
+1;
+
+sub headerGetEntry {
+ my ($h, $q) = @_;
+
+ $q eq 'name' and return headerGetEntry_string($h, RPMTAG_NAME());
+ $q eq 'group' and return headerGetEntry_string($h, RPMTAG_GROUP());
+ $q eq 'version' and return headerGetEntry_string($h, RPMTAG_VERSION());
+ $q eq 'release' and return headerGetEntry_string($h, RPMTAG_RELEASE());
+ $q eq 'summary' and return headerGetEntry_string($h, RPMTAG_SUMMARY());
+ $q eq 'description' and return headerGetEntry_string($h, RPMTAG_DESCRIPTION());
+ $q eq 'arch' and return headerGetEntry_string($h, RPMTAG_ARCH());
+ $q eq 'size' and return headerGetEntry_int($h, RPMTAG_SIZE());
+ $q eq 'filenames' and return headerGetEntry_string_list($h, RPMTAG_FILENAMES());
+ $q eq 'obsoletes' and return headerGetEntry_string_list($h, RPMTAG_OBSOLETES());
+}
+
diff --git a/perl-install/c/stuff.xs.pm b/perl-install/c/stuff.xs.pm
new file mode 100644
index 000000000..2b301d1b0
--- /dev/null
+++ b/perl-install/c/stuff.xs.pm
@@ -0,0 +1,576 @@
+print '
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <resolv.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+#include <linux/fs.h>
+#include <linux/hdreg.h>
+#include <linux/vt.h>
+#include <net/if.h>
+#include <net/route.h>
+
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#define SECTORSIZE 512
+';
+
+$ENV{C_RPM} and print '
+#include <rpm/rpmlib.h>
+
+void rpmError_callback_empty(void) {}
+
+int rpmError_callback_data;
+void rpmError_callback(void) {
+ if (rpmErrorCode() != RPMERR_UNLINK && rpmErrorCode() != RPMERR_RMDIR) {
+ write(rpmError_callback_data, rpmErrorString(), strlen(rpmErrorString()));
+ write(rpmError_callback_data, "\n", 1);
+ }
+}
+
+FD_t fd2FD_t(int fd) {
+ static struct _FD f = { -1, NULL, NULL, NULL };
+ f.fd_fd = fd;
+ return fd == -1 ? NULL : &f;
+}
+
+';
+
+print '
+
+long long llseek(int fd, long long offset, int whence);
+
+MODULE = c::stuff PACKAGE = c::stuff
+
+int
+Xtest(display)
+ char *display
+ CODE:
+ int pid;
+ if ((pid = fork()) == 0) {
+ Display *d = XOpenDisplay(display);
+ if (d) {
+ XSetCloseDownMode(d, RetainPermanent);
+ XCloseDisplay(d);
+ }
+ {
+ char *args[2];
+ args[0] = d ? "false" : "true"; /* inverted on purpose! */
+ args[1] = NULL;
+ execvp(args[0], args);
+ }
+ printf("***************** SHOUDNT GET THERE ***************\n");
+ exit(d != NULL);
+ }
+
+ waitpid(pid, &RETVAL, 0);
+ OUTPUT:
+ RETVAL
+
+void
+XSetInputFocus(window)
+ int window
+ CODE:
+ XSetInputFocus(GDK_DISPLAY(), window, RevertToParent, CurrentTime);
+
+int
+KTYP(x)
+ int x
+ CODE:
+ RETVAL = KTYP(x);
+ OUTPUT:
+ RETVAL
+
+int
+lseek_sector(fd, sector, offset)
+ int fd
+ long sector
+ long offset
+ CODE:
+ RETVAL = llseek(fd, (long long) sector * SECTORSIZE + offset, SEEK_SET) >= 0;
+ OUTPUT:
+ RETVAL
+
+void
+setsid()
+
+unsigned int
+getpagesize()
+
+int
+loadFont(fontFile)
+ char *fontFile
+ CODE:
+ char font[8192];
+ unsigned short map[E_TABSZ];
+ struct unimapdesc d;
+ struct unimapinit u;
+ struct unipair desc[2048];
+ int rc = 0;
+
+ int fd = open(fontFile, O_RDONLY);
+ read(fd, font, sizeof(font));
+ read(fd, map, sizeof(map));
+ read(fd, &d.entry_ct, sizeof(d.entry_ct));
+ d.entries = desc;
+ read(fd, desc, d.entry_ct * sizeof(desc[0]));
+ close(fd);
+
+ rc = ioctl(1, PIO_FONT, font);
+ rc = ioctl(1, PIO_UNIMAPCLR, &u) || rc;
+ rc = ioctl(1, PIO_UNIMAP, &d) || rc;
+ rc = ioctl(1, PIO_UNISCRNMAP, map) || rc;
+ RETVAL = rc == 0;
+ OUTPUT:
+ RETVAL
+
+int
+hasNetDevice(device)
+ char * device
+ CODE:
+ struct ifreq req;
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1) { RETVAL = 0; return; }
+
+ strcpy(req.ifr_name, device);
+
+ RETVAL = ioctl(s, SIOCGIFFLAGS, &req) == 0;
+ if (!RETVAL) close(s);
+ OUTPUT:
+ RETVAL
+
+int
+addDefaultRoute(gateway)
+ char *gateway
+ CODE:
+ struct rtentry route;
+ struct sockaddr_in addr;
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1) { RETVAL = 0; return; }
+
+ memset(&route, 0, sizeof(route));
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ inet_aton(gateway, &addr.sin_addr);
+ memcpy(&route.rt_gateway, &addr, sizeof(addr));
+
+ addr.sin_addr.s_addr = INADDR_ANY;
+ memcpy(&route.rt_dst, &addr, sizeof(addr));
+ memcpy(&route.rt_genmask, &addr, sizeof(addr));
+
+ route.rt_flags = RTF_UP | RTF_GATEWAY;
+ route.rt_metric = 0;
+
+ RETVAL = !ioctl(s, SIOCADDRT, &route);
+ OUTPUT:
+ RETVAL
+
+char *
+kernel_version()
+ CODE:
+ struct utsname u;
+ if (uname(&u) == 0) RETVAL = u.release; else RETVAL = NULL;
+ OUTPUT:
+ RETVAL
+
+
+';
+
+$ENV{C_RPM} and print '
+int
+rpmReadConfigFiles()
+ CODE:
+ RETVAL = rpmReadConfigFiles(NULL, NULL) == 0;
+ OUTPUT:
+ RETVAL
+
+int
+rpmdbInit(root, perms)
+ char *root
+ int perms
+ CODE:
+ RETVAL = rpmdbInit(root, perms) == 0;
+ OUTPUT:
+ RETVAL
+
+void *
+rpmdbOpen(root)
+ char *root
+ CODE:
+ static rpmdb db;
+ RETVAL = rpmdbOpen(root, &db, O_RDWR | O_CREAT, 0644) == 0 ||
+ rpmdbOpen(root, &db, O_RDONLY, 0644) == 0 ? db : NULL;
+ OUTPUT:
+ RETVAL
+
+void *
+rpmdbOpenForTraversal(root)
+ char *root
+ CODE:
+ static rpmdb db;
+ RETVAL = rpmdbOpenForTraversal(root, &db) == 0 ? db : NULL;
+ OUTPUT:
+ RETVAL
+
+void
+rpmdbClose(db)
+ void *db
+
+int
+rpmdbTraverse(db, ...)
+ void *db
+ PREINIT:
+ SV *callback = &PL_sv_undef;
+ int num, count;
+ Header h;
+ CODE:
+ if (items > 1) {
+ callback = ST(1);
+ }
+ count = 0;
+ num = rpmdbFirstRecNum(db);
+ while (num) {
+ if (callback != &PL_sv_undef && SvROK(callback)) {
+ h = rpmdbGetRecord(db, num);
+ {
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSViv((IV)(void *)h)));
+ PUTBACK;
+ perl_call_sv(callback, G_DISCARD | G_SCALAR);
+ FREETMPS;
+ LEAVE;
+ }
+ headerFree(h);
+ }
+ num = rpmdbNextRecNum(db, num);
+ ++count;
+ }
+ RETVAL = count;
+ OUTPUT:
+ RETVAL
+
+int
+rpmdbNameTraverse(db, name, ...)
+ void *db
+ char *name
+ PREINIT:
+ SV *callback = &PL_sv_undef;
+ int i, rc;
+ Header h;
+ rpmErrorCallBackType oldcb;
+ dbiIndexSet matches;
+ CODE:
+ if (items > 2) {
+ callback = ST(2);
+ }
+ rc = rpmdbFindPackage(db, name, &matches);
+ if (rc == 0) {
+ RETVAL = matches.count;
+ if (callback != &PL_sv_undef && SvROK(callback) && matches.count > 0) {
+ oldcb = rpmErrorSetCallback(rpmError_callback_empty);
+ for (i = 0; i < matches.count; ++i) {
+ h = rpmdbGetRecord(db, matches.recs[i].recOffset);
+
+ {
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSViv((IV)(void *)h)));
+ PUTBACK;
+ perl_call_sv(callback, G_DISCARD | G_SCALAR);
+ FREETMPS;
+ LEAVE;
+ }
+
+ headerFree(h);
+ }
+ rpmErrorSetCallback(oldcb);
+ }
+ dbiFreeIndexRecord(matches);
+ } else
+ RETVAL = 0;
+ OUTPUT:
+ RETVAL
+
+
+void *
+rpmtransCreateSet(db, rootdir)
+ void *db
+ char *rootdir
+
+void
+rpmtransAvailablePackage(rpmdep, header, key)
+ void *rpmdep
+ void *header
+ char *key
+ CODE:
+ rpmtransAvailablePackage(rpmdep, header, strdup(key));
+
+int
+rpmtransAddPackage(rpmdep, header, key, update)
+ void *rpmdep
+ void *header
+ char *key
+ int update
+ CODE:
+ rpmTransactionSet r = rpmdep;
+ RETVAL = rpmtransAddPackage(r, header, NULL, strdup(key), update, NULL) == 0;
+ OUTPUT:
+ RETVAL
+
+int
+rpmdepOrder(order)
+ void *order
+ CODE:
+ RETVAL = rpmdepOrder(order) == 0;
+ OUTPUT:
+ RETVAL
+
+void
+rpmdepCheck(rpmdep)
+ void *rpmdep
+ PPCODE:
+ struct rpmDependencyConflict * conflicts;
+ int numConflicts, i;
+ rpmdepCheck(rpmdep, &conflicts, &numConflicts);
+ if (numConflicts) {
+ EXTEND(SP, numConflicts);
+ for (i = 0; i < numConflicts; i++)
+ if (conflicts[i].sense == RPMDEP_SENSE_CONFLICTS) {
+ fprintf(stderr, "%s conflicts with %s\n", conflicts[i].byName, conflicts[i].needsName);
+ } else {
+ if (conflicts[i].suggestedPackage)
+ PUSHs(sv_2mortal(newSVpv((char *) conflicts[i].suggestedPackage, 0)));
+ else {
+ char *p = malloc(100 + strlen(conflicts[i].needsName) + strlen(conflicts[i].byName));
+ sprintf(p, "%s needed but nothing provide it (%s)", conflicts[i].needsName, conflicts[i].byName);
+ PUSHs(sv_2mortal(newSVpv(p, 0)));
+ free(p);
+ }
+ }
+ }
+
+void
+rpmdepCheckFrom(rpmdep)
+ void *rpmdep
+ PPCODE:
+ struct rpmDependencyConflict * conflicts;
+ int numConflicts, i;
+ rpmdepCheck(rpmdep, &conflicts, &numConflicts);
+ if (numConflicts) {
+ EXTEND(SP, numConflicts);
+ for (i = 0; i < numConflicts; i++)
+ PUSHs(sv_2mortal(newSVpv(conflicts[i].byName, 0)));
+ }
+
+int
+rpmdbRebuild(root)
+ char *root
+ CODE:
+ RETVAL = rpmdbRebuild(root) == 0;
+ OUTPUT:
+ RETVAL
+
+void
+rpmtransFree(trans)
+ void *trans
+
+char *
+rpmErrorString()
+
+int
+rpmVersionCompare(headerFirst, headerSecond)
+ void *headerFirst
+ void *headerSecond
+
+void
+rpmSetVeryVerbose()
+ CODE:
+ rpmSetVerbosity(RPMMESS_DEBUG);
+
+void
+rpmtransSetScriptFd(trans, fd)
+ void *trans
+ int fd
+ CODE:
+ rpmtransSetScriptFd(trans, fdDup(fd));
+
+void
+rpmRunTransactions(trans, callbackOpen, callbackClose, callbackStart, callbackProgress, force)
+ void *trans
+ SV *callbackOpen
+ SV *callbackClose
+ SV *callbackStart
+ SV *callbackProgress
+ int force
+ PPCODE:
+ rpmProblemSet probs;
+ void *rpmRunTransactions_callback(const Header h, const rpmCallbackType what, const unsigned long amount, const unsigned long total, const void * pkgKey, void * data) {
+ static FD_t fd;
+ static int last_amount;
+ char *n = (char *) pkgKey;
+
+ switch (what) {
+ case RPMCALLBACK_INST_OPEN_FILE: {
+ int i;
+ dSP;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSVpv(n, 0)));
+ PUTBACK;
+ i = perl_call_sv(callbackOpen, G_SCALAR);
+ SPAGAIN;
+ if (i != 1) croak("Big trouble\n");
+ fd = fd2FD_t(POPi);
+ PUTBACK;
+ return fd;
+ }
+
+ case RPMCALLBACK_INST_CLOSE_FILE: {
+ dSP;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSVpv(n, 0)));
+ PUTBACK;
+ perl_call_sv(callbackClose, G_DISCARD);
+ free(n); /* was strdup in rpmtransAddPackage */
+ break;
+ }
+
+ case RPMCALLBACK_INST_START: {
+ dSP ;
+ PUSHMARK(sp) ;
+ XPUSHs(sv_2mortal(newSVpv(n, 0)));
+ PUTBACK ;
+ perl_call_sv(callbackStart, G_DISCARD);
+ last_amount = 0;
+ } break;
+
+ case RPMCALLBACK_INST_PROGRESS:
+ if ((amount - last_amount) * 4 / total) {
+ dSP;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSViv(amount)));
+ XPUSHs(sv_2mortal(newSViv(total)));
+ PUTBACK ;
+ perl_call_sv(callbackProgress, G_DISCARD);
+ last_amount = amount;
+ } break;
+ default: break;
+ }
+ return NULL;
+ }
+ if (rpmRunTransactions(trans, rpmRunTransactions_callback, NULL, NULL, &probs, 0, force ? ~0 : ~RPMPROB_FILTER_DISKSPACE)) {
+ int i;
+ EXTEND(SP, probs->numProblems);
+ for (i = 0; i < probs->numProblems; i++) {
+ PUSHs(sv_2mortal(newSVpv(rpmProblemString(probs->probs[i]), 0)));
+ }
+ }
+
+void
+rpmErrorSetCallback(fd)
+ int fd
+ CODE:
+ rpmError_callback_data = fd;
+ rpmErrorSetCallback(rpmError_callback);
+
+void *
+rpmReadPackageHeader(fd)
+ int fd
+ CODE:
+ Header h;
+ int isSource, major;
+ RETVAL = rpmReadPackageHeader(fd2FD_t(fd), &h, &isSource, &major, NULL) ? NULL : h;
+ OUTPUT:
+ RETVAL
+
+void *
+headerRead(fd, magicp)
+ int fd
+ int magicp
+ CODE:
+ RETVAL = (void *) headerRead(fd2FD_t(fd), magicp);
+ OUTPUT:
+ RETVAL
+
+char *
+headerGetEntry_string(h, query)
+ void *h
+ int query
+ CODE:
+ int type, count;
+ headerGetEntry((Header) h, query, &type, (void **) &RETVAL, &count);
+ OUTPUT:
+ RETVAL
+
+int
+headerGetEntry_int(h, query)
+ void *h
+ int query
+ CODE:
+ int type, count, *i;
+ headerGetEntry((Header) h, query, &type, (void **) &i, &count);
+ RETVAL = *i;
+ OUTPUT:
+ RETVAL
+
+void
+headerGetEntry_string_list(h, query)
+ void *h
+ int query
+ PPCODE:
+ int i, type, count = 0;
+ char **strlist = (char **) NULL;
+ if (headerGetEntry((Header) h, query, &type, (void**) &strlist, &count) && count) {
+ EXTEND(SP, count);
+ for (i = 0; i < count; i++) {
+ PUSHs(sv_2mortal(newSVpv(strlist[i], 0)));
+ }
+ }
+ free(strlist);
+';
+
+@macros = (
+ [ qw(int S_IFCHR S_IFBLK KDSKBENT KT_SPEC NR_KEYS MAX_NR_KEYMAPS BLKRRPART TIOCSCTTY
+ HDIO_GETGEO BLKGETSIZE
+ MS_MGC_VAL MS_RDONLY O_NONBLOCK SECTORSIZE WNOHANG
+ VT_ACTIVATE VT_WAITACTIVE VT_GETSTATE
+ ) ],
+);
+push @macros, [ qw(int RPMTAG_NAME RPMTAG_GROUP RPMTAG_SIZE RPMTAG_VERSION RPMTAG_SUMMARY RPMTAG_DESCRIPTION RPMTAG_RELEASE RPMTAG_ARCH RPMTAG_FILENAMES RPMTAG_OBSOLETES) ]
+ if $ENV{C_RPM};
+
+$\= "\n";
+print;
+
+foreach (@macros) {
+ my ($type, @l) = @$_;
+ foreach (@l) {
+ print<< "END"
+$type
+$_()
+ CODE:
+ RETVAL = $_;
+
+ OUTPUT:
+ RETVAL
+
+END
+
+ }
+}