aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile19
-rw-r--r--gendepslist.cc212
-rw-r--r--hdlist2files.cc46
-rw-r--r--hdlist2names.cc46
-rw-r--r--rpm-find-leaves.c49
-rw-r--r--rpm2header.c78
-rw-r--r--rpmtools.spec65
7 files changed, 515 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..357ec5e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,19 @@
+FROMC = rpm2header #rpm-find-leaves
+FROMCC = gendepslist hdlist2names hdlist2files
+ALL = $(FROMC) $(FROMCC)
+LIBRPM = /usr/lib/librpm.so.0 -ldb1 -lz -I/usr/include/rpm -lpopt
+
+all: $(ALL)
+
+install: $(ALL)
+ install -d $(PREFIX)/usr/bin
+ install -s $(ALL) $(PREFIX)/usr/bin
+
+$(FROMCC): %: %.cc
+ $(CXX) $(CFLAGS) $< $(LIBRPM) -o $@
+
+$(FROMC): %: %.c
+ $(CC) $(CFLAGS) $< $(LIBRPM) -o $@
+
+clean:
+ rm -rf *~ $(ALL)
diff --git a/gendepslist.cc b/gendepslist.cc
new file mode 100644
index 0000000..60cb62a
--- /dev/null
+++ b/gendepslist.cc
@@ -0,0 +1,212 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <rpm/rpmlib.h>
+#include <rpm/header.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <fstream>
+#include <algorithm>
+
+
+string get_name(Header header, int_32 tag) {
+ int_32 type, count;
+ char *name;
+
+ headerGetEntry(header, tag, &type, (void **) &name, &count);
+ return string(name);
+}
+
+int get_int(Header header, int_32 tag) {
+ int_32 type, count;
+ int *i;
+
+ headerGetEntry(header, tag, &type, (void **) &i, &count);
+ return *i;
+}
+
+vector<string> get_info(Header header, int_32 tag) {
+ int_32 type, count, i;
+ vector<string> r;
+ char **list;
+
+ headerGetEntry(header, tag, &type, (void **) &list, &count);
+ if (list) {
+ r.reserve(count);
+ for (i = 0; i < count; i++) r.push_back(list[i]);
+ }
+ return r;
+}
+
+template<class V, class C> C sum(const V &v, const C &join = C()) {
+ typename V::const_iterator p, q;
+ C s = C();
+ if (v.begin() != v.end()) {
+ for (p = q = v.begin(), q++; q != v.end(); p = q, q++) s += *p + join;
+ s += *p;
+ }
+ return s;
+}
+
+template<class A, class B> void map_insert(map<A, set<B> > &m, const A &a, const B &b) {
+ if (m.find(a) == m.end()) m[a] = *(new set<B>);
+ m[a].insert(b);
+}
+
+template<class A> bool in(const A &a, const vector<A> &v) {
+ vector<A>::const_iterator p;
+ for (p = v.begin(); p != v.end(); p++) if (*p == a) return 1;
+ return 0;
+}
+
+typedef vector<string>::iterator IT;
+
+#define myerror(e) { checknberrors(); e; return; }
+
+struct pack {
+ int nberrors;
+ static const int max_errors = 20;
+ ofstream html, text;
+ vector<string> packages;
+ map<string, string> short_name;
+ map<string, int> size;
+ map<string, vector<string> > requires;
+ map<string, set<string> > provides;
+ map<string, set<set<string> > > pack_requires;
+
+ pack(string name) : nberrors(0), html((name + ".html").c_str()), text(name.c_str()) {
+ if (!html || !text) {
+ cerr << "rpmpackdeps: can't output files\n";
+ exit(1);
+ }
+ }
+
+ void checknberrors() {
+ if (nberrors++ == max_errors) {
+ cerr << "rpmpackdeps: too many errors, leaving!\n";
+ exit(1);
+ }
+ }
+
+ int get_package_info(Header header) {
+
+ string s_name = get_name(header, RPMTAG_NAME);
+ string name = s_name + "-" + get_name(header, RPMTAG_VERSION) + "-" + get_name(header, RPMTAG_RELEASE);
+
+ packages.push_back(name);
+ short_name[name] = s_name;
+ requires[name] = get_info(header, RPMTAG_REQUIRENAME);
+ size[name] = get_int(header, RPMTAG_SIZE);
+ map_insert(provides, s_name, name);
+
+ vector<string> provide = get_info(header, RPMTAG_PROVIDES);
+ vector<string> files = get_info(header, RPMTAG_OLDFILENAMES);
+ for (IT p = provide.begin(); p != provide.end(); p++) map_insert(provides, *p, name);
+ for (IT p = files.begin(); p != files.end(); p++) map_insert(provides, *p, name);
+ headerFree(header);
+ return 1;
+ }
+
+ void sort() {
+ std::sort(packages.begin(), packages.end());
+ }
+
+ set<set<string> > closure(const string &package) {
+ if (pack_requires.find(package) != pack_requires.end()) return pack_requires[package];
+
+ set<set<string> > l;
+ pack_requires[package] = l; // to avoid circular graphs
+
+ for (IT q = requires[package].begin(); q != requires[package].end(); q++) {
+ set<string> s;
+ if (provides.find(*q) == provides.end()) {
+ cerr << package << " requires " << *q << " but no package provide it\n";
+ s.insert("NOTFOUND_" + *q);
+ } else {
+ for (set<string>::const_iterator p = provides[*q].begin(); p != provides[*q].end(); p++) {
+ if (*p == package) { s.clear(); break; }
+ s.insert(*p);
+ }
+
+ if (provides[*q].size() == 1) {
+#ifdef CLOSURE
+ set<set<string> > c = closure(st);
+ l.insert(c.begin(), c.end());
+#endif
+ }
+ }
+ l.insert(s);
+ }
+ return pack_requires[package] = l;
+ }
+
+ void print_deps() {
+ html << "<html><dl>\n";
+ for (IT package = packages.begin(); package != packages.end(); package++) {
+ set<set<string> > l = closure(*package);
+
+ text << *package << " " << size[*package] << " ";
+ html << "<dt>" << *package << "<dd>";
+ for (set<set<string> >::const_iterator p = l.begin(); p != l.end(); p++) {
+ text << sum(*p, string("|")) << " ";
+ html << sum(*p, string(" or ")) << "<br>";
+ }
+ text << "\n";
+ html << "\n";
+ }
+ html << "</dl></html>\n";
+ }
+};
+
+void printHelp(char * name)
+{
+ cerr << "usage: \n" << name << " -h name hdlists...\n" << name << " -f name rpms...\n";
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 3) {
+ if (!strcmp(argv[1],"-h")) { //Mode Hdlist
+ pack p(argv[2]);
+ for (int i = 3; i < argc; i++)
+ {
+ FD_t fd = strcmp(argv[i], "-") == 0 ? fdDup(STDIN_FILENO) : fdOpen(argv[i], O_RDONLY, 0);
+ if (fdFileno(fd) < 0) cerr << "rpmpackdeps: cannot open file " << argv[i] << "\n";
+ else {
+ Header header;
+ while ((header=headerRead(fd, HEADER_MAGIC_YES))) p.get_package_info(header);
+ }
+ fdClose(fd);
+ }
+ p.sort();
+ p.print_deps();
+ return 0;
+ }
+ else {
+ int i=2;
+ if (!strcmp(argv[1],"-f")) i++;
+ //Mode rpm
+ pack p(argv[2]);
+ for (int i = 3; i < argc; i++)
+ {
+ FD_t fd = fdOpen(argv[i], O_RDONLY, 0);
+ if (fdFileno(fd) < 0) cerr << argv[0] << ": cannot open file " << argv[i] << "\n";
+ Header header;
+ if (rpmReadPackageInfo(fd, NULL, &header)) cerr << argv[0] <<" : " << argv[i] << " does not appear to be a RPM package\n";
+ else p.get_package_info(header);
+ fdClose(fd);
+ }
+ p.sort();
+ p.print_deps();
+ return 0;
+ }
+ }
+ else
+ {
+ printHelp(argv[0]);
+ return 1;
+ }
+}
+
diff --git a/hdlist2files.cc b/hdlist2files.cc
new file mode 100644
index 0000000..1654886
--- /dev/null
+++ b/hdlist2files.cc
@@ -0,0 +1,46 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <rpm/rpmlib.h>
+#include <rpm/header.h>
+#include <iostream>
+
+
+char *get_name(Header header, int_32 tag) {
+ int_32 type, count;
+ char *name;
+
+ headerGetEntry(header, tag, &type, (void **) &name, &count);
+ return name;
+}
+
+int get_int(Header header, int_32 tag) {
+ int_32 type, count;
+ int *i;
+
+ headerGetEntry(header, tag, &type, (void **) &i, &count);
+ return *i;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc <= 1) {
+ cerr << "usage: hdlist2files <hdlist> [<hdlists...>]\n";
+ exit(1);
+ }
+ for (int i = 1; i < argc; i++) {
+ FD_t fd = strcmp(argv[i], "-") == 0 ? fdDup(STDIN_FILENO) : fdOpen(argv[i], O_RDONLY, 0);
+ if (fdFileno(fd) < 0) cerr << "rpmpackdeps: cannot open file " << argv[i] << "\n";
+ else {
+ Header header;
+ int_32 type, count;
+ char **list;
+ while ((header=headerRead(fd, HEADER_MAGIC_YES))) {
+ char *name = get_name(header, RPMTAG_NAME);
+ headerGetEntry(header, RPMTAG_OLDFILENAMES, &type, (void **) &list, &count);
+ if (list) for (i = 0; i < count; i++) printf("%s:%s\n", name, list[i]);
+ }
+ }
+ fdClose(fd);
+ }
+}
diff --git a/hdlist2names.cc b/hdlist2names.cc
new file mode 100644
index 0000000..cdb0c32
--- /dev/null
+++ b/hdlist2names.cc
@@ -0,0 +1,46 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <rpm/rpmlib.h>
+#include <rpm/header.h>
+#include <iostream>
+
+
+char *get_name(Header header, int_32 tag) {
+ int_32 type, count;
+ char *name;
+
+ headerGetEntry(header, tag, &type, (void **) &name, &count);
+ return name;
+}
+
+int get_int(Header header, int_32 tag) {
+ int_32 type, count;
+ int *i;
+
+ headerGetEntry(header, tag, &type, (void **) &i, &count);
+ return *i;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc <= 1) {
+ cerr << "usage: hdlist2names <hdlist> [<hdlists...>]\n";
+ exit(1);
+ }
+ for (int i = 1; i < argc; i++) {
+ FD_t fd = strcmp(argv[i], "-") == 0 ? fdDup(STDIN_FILENO) : fdOpen(argv[i], O_RDONLY, 0);
+ if (fdFileno(fd) < 0) cerr << "rpmpackdeps: cannot open file " << argv[i] << "\n";
+ else {
+ Header header;
+ while ((header=headerRead(fd, HEADER_MAGIC_YES))) {
+ printf("%s-%s-%s.%s.rpm\n",
+ get_name(header, RPMTAG_NAME),
+ get_name(header, RPMTAG_VERSION),
+ get_name(header, RPMTAG_RELEASE),
+ get_name(header, RPMTAG_ARCH));
+ }
+ }
+ fdClose(fd);
+ }
+}
diff --git a/rpm-find-leaves.c b/rpm-find-leaves.c
new file mode 100644
index 0000000..c72337a
--- /dev/null
+++ b/rpm-find-leaves.c
@@ -0,0 +1,49 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <rpm/rpmlib.h>
+#include <rpm/header.h>
+
+static Header header;
+
+#define die(f) { perror(f); exit(1); }
+
+rpmdb open_rpmdb(void) {
+ rpmdb db;
+ if (rpmdbOpen("", &db, O_RDONLY, 0644)) die("rpmdbOpen");
+ return db;
+}
+
+char *get(int_32 tag) {
+ int_32 type, count;
+ char *s;
+ if (headerGetEntry(header, tag, &type, (void **) &s, &count) != 1) die("bad header ??");
+ return s;
+}
+
+
+int main() {
+ rpmTransactionSet trans;
+ struct rpmDependencyConflict *conflicts;
+ int numConflicts;
+ rpmdb db;
+ int i;
+
+ rpmReadConfigFiles(NULL, NULL);
+
+ db = open_rpmdb();
+
+ for(i = rpmdbFirstRecNum(db); i; i = rpmdbNextRecNum(db, i)) {
+ trans = rpmtransCreateSet(db, NULL);
+ rpmtransRemovePackage(trans, i);
+ if (rpmdepCheck(trans, &conflicts, &numConflicts)) die("rpmdepCheck");
+ if (numConflicts == 0) {
+ header = rpmdbGetRecord(db, i);
+ printf("%s-%s-%s\n", get(RPMTAG_NAME), get(RPMTAG_VERSION), get(RPMTAG_RELEASE));
+ headerFree(header);
+ }
+ rpmdepFreeConflicts(conflicts, numConflicts);
+ rpmtransFree(trans);
+ }
+ exit(0);
+}
diff --git a/rpm2header.c b/rpm2header.c
new file mode 100644
index 0000000..32ace46
--- /dev/null
+++ b/rpm2header.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <rpmlib.h>
+
+#define FILENAME_TAG 1000000
+#define FILESIZE_TAG 1000001
+
+const char *basename(const char *f) {
+ char *p = strrchr(f, '/');
+ return p ? p + 1 : f;
+}
+
+int_32 FD_size(FD_t fd) {
+ struct stat sb;
+ fstat(fdFileno(fd), &sb);
+ return sb.st_size;
+}
+
+int main(int argc, char **argv) {
+ int i;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: rpm2header <rpms>\n");
+ exit(1);
+ }
+
+ for (i = 1; i < argc; i++) {
+ FD_t fd;
+ Header h;
+ int isSource;
+ int_32 size;
+ const char *name = basename(argv[i]);
+
+ if (!(fd = fdOpen(argv[i], O_RDONLY, 0666))) {
+ perror("open");
+ exit(1);
+ }
+ size = FD_size(fd);
+
+ if (rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL) == 0) {
+ headerRemoveEntry(h, RPMTAG_POSTIN);
+ headerRemoveEntry(h, RPMTAG_POSTUN);
+ headerRemoveEntry(h, RPMTAG_PREIN);
+ headerRemoveEntry(h, RPMTAG_PREUN);
+ headerRemoveEntry(h, RPMTAG_FILEUSERNAME);
+ headerRemoveEntry(h, RPMTAG_FILEGROUPNAME);
+ headerRemoveEntry(h, RPMTAG_FILEVERIFYFLAGS);
+ headerRemoveEntry(h, RPMTAG_FILERDEVS);
+ headerRemoveEntry(h, RPMTAG_FILEMTIMES);
+ headerRemoveEntry(h, RPMTAG_FILEDEVICES);
+ headerRemoveEntry(h, RPMTAG_FILEINODES);
+ headerRemoveEntry(h, RPMTAG_TRIGGERSCRIPTS);
+ headerRemoveEntry(h, RPMTAG_TRIGGERVERSION);
+ headerRemoveEntry(h, RPMTAG_TRIGGERFLAGS);
+ headerRemoveEntry(h, RPMTAG_TRIGGERNAME);
+ headerRemoveEntry(h, RPMTAG_CHANGELOGTIME);
+ headerRemoveEntry(h, RPMTAG_CHANGELOGNAME);
+ headerRemoveEntry(h, RPMTAG_CHANGELOGTEXT);
+ headerRemoveEntry(h, RPMTAG_ICON);
+ headerRemoveEntry(h, RPMTAG_GIF);
+ headerRemoveEntry(h, RPMTAG_VENDOR);
+ headerRemoveEntry(h, RPMTAG_EXCLUDE);
+ headerRemoveEntry(h, RPMTAG_EXCLUSIVE);
+ headerRemoveEntry(h, RPMTAG_DISTRIBUTION);
+ headerRemoveEntry(h, RPMTAG_VERIFYSCRIPT);
+ headerAddEntry(h, FILENAME_TAG, RPM_STRING_TYPE, name, 1);
+ headerAddEntry(h, FILESIZE_TAG, RPM_INT32_TYPE, &size, 1);
+ headerWrite(fdDup(1 /*stdout*/), h, HEADER_MAGIC_YES);
+ headerFree(h);
+ }
+ }
+ return 0;
+}
diff --git a/rpmtools.spec b/rpmtools.spec
new file mode 100644
index 0000000..8dfe546
--- /dev/null
+++ b/rpmtools.spec
@@ -0,0 +1,65 @@
+%define name rpmtools
+%define version 1.0
+%define release 8mdk
+
+Summary: contains various rpm command-line tools
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Source0: %{name}.tar.bz2
+Copyright: GPL
+Group: System Environment/Base
+BuildRoot: /tmp/%{name}-buildroot
+Prefix: %{_prefix}
+BuildRequires: rpm-
+
+%description
+Various rpmtools.
+
+%prep
+%setup -n %{name}
+
+%build
+make
+
+%install
+make install PREFIX=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+/usr/bin/*
+
+
+%changelog
+* Thu Feb 17 2000 Chmouel Boudjnah <chmouel@mandrakesoft.com> 1.0-8mdk
+- Porting to rpm-3.0.4.
+
+* Tue Jan 4 2000 Pixel <pixel@mandrakesoft.com>
+- renamed hdlist2files in hdlist2names
+- added hdlist2files
+
+* Sun Dec 19 1999 Pixel <pixel@mandrakesoft.com>
+- added ability to read from stdin to hdlist2files
+
+* Sat Dec 18 1999 Pixel <pixel@mandrakesoft.com>
+- modified gendepslist to accept hdlist's from stdin
+
+* Thu Nov 25 1999 Pixel <pixel@linux-mandrake.com>
+- removed rpm-find-leaves (now in urpmi)
+
+* Sun Nov 21 1999 Pixel <pixel@mandrakesoft.com>
+- now installed in /usr/bin
+- added rpm-find-leaves
+- replaced -lrpm by /usr/lib/librpm.so.0 to make it dynamic
+(why is this needed?)
+
+* Mon Nov 15 1999 Pixel <pixel@mandrakesoft.com>
+
+- first version
+
+
+# end of file