diff options
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | gendepslist.cc | 212 | ||||
-rw-r--r-- | hdlist2files.cc | 46 | ||||
-rw-r--r-- | hdlist2names.cc | 46 | ||||
-rw-r--r-- | rpm-find-leaves.c | 49 | ||||
-rw-r--r-- | rpm2header.c | 78 | ||||
-rw-r--r-- | rpmtools.spec | 65 |
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 |