Capture rpm-3.0.3 examples from "Maximum RPM".
CVS patchset: 5306 CVS date: 2002/02/09 19:21:34
This commit is contained in:
parent
380b21d69e
commit
8ddeef05cd
|
@ -0,0 +1,21 @@
|
|||
# Makes the Maxumum RPM example programs
|
||||
# Scott Bronson, 20 Mar 1999
|
||||
|
||||
# NOTE: if you do not have libdb1, change this makefile to use libdb
|
||||
# (or whatever database library rpm was compiled with).
|
||||
|
||||
|
||||
all: dumprpm showdb showdb2
|
||||
|
||||
dumprpm: dumprpm.c
|
||||
gcc -Wall dumprpm.c -lrpm -lintl -lgz -o dumprpm
|
||||
|
||||
showdb: showdb.c
|
||||
gcc -Wall showdb.c -lrpm -lintl -ldb1 -lgz -o showdb
|
||||
|
||||
showdb2: showdb2.c
|
||||
gcc -Wall showdb2.c -lrpm -lintl -ldb1 -lgz -o showdb2
|
||||
|
||||
clean:
|
||||
rm -f dumprpm showdb showdb2
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
readme
|
||||
Scott Bronson
|
||||
4 Oct 99
|
||||
|
||||
|
||||
These are the example programs from MaximumRPM, updated to today's rpmlib.
|
||||
You can find MaximumRPM on the http://www.rpm.org/ site.
|
||||
|
||||
To build these, edit the makefile as appropriate (if you're using gcc,
|
||||
you should not have to change anything), then "make all". 3 utilities
|
||||
will be built:
|
||||
|
||||
|
||||
dumprpm: % dumprpm filename
|
||||
|
||||
Dumps a textual description of the the contents of the named RPM
|
||||
file on disk.
|
||||
|
||||
|
||||
showdb: % showdb rpmname
|
||||
|
||||
Dumps a textual description of the named RPM. The RPM must be
|
||||
currently installed in the database.
|
||||
|
||||
|
||||
showdb2: % showdb2 rpmname
|
||||
|
||||
Dumps a textual description of the named RPM, like showdb. However,
|
||||
uses a database query rather than a brute-force scan to locate the
|
||||
rpm (should be much more efficient).
|
||||
|
||||
|
||||
|
||||
You will also find the string.txt file. This documents the only
|
||||
difficulty I had updating these programs.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/* Example 1 from Maximum RPM book by Edward C. Bailey
|
||||
* Updated for 2.5.6 Mar 99 by Scott Bronson
|
||||
* Updated again for 3.0.3, 4 Oct 99.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rpm/rpmlib.h>
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
HeaderIterator iter;
|
||||
Header h, sig;
|
||||
int_32 itertag, type, count;
|
||||
void *p = NULL;
|
||||
char *name;
|
||||
FD_t fd;
|
||||
int stat;
|
||||
|
||||
if( argc == 1 ) {
|
||||
fd = fdDup( STDIN_FILENO );
|
||||
} else {
|
||||
fd = fdOpen( argv[1], O_RDONLY, 0644 );
|
||||
}
|
||||
|
||||
if( !fdValid(fd) ) {
|
||||
perror( "open" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
stat = rpmReadPackageInfo( fd, &sig, &h );
|
||||
if( stat ) {
|
||||
fprintf( stderr, "rpmReadPackageInfo error status: %d\n%s\n",
|
||||
stat, strerror(errno) );
|
||||
exit( stat );
|
||||
}
|
||||
|
||||
headerGetEntry( h, RPMTAG_NAME, &type, (void**)&name, &count );
|
||||
|
||||
if( headerIsEntry(h,RPMTAG_PREIN) ) {
|
||||
printf( "There is a preinstall script for %s\n", name );
|
||||
}
|
||||
if( headerIsEntry(h,RPMTAG_POSTIN) ) {
|
||||
printf( "There is a postinstall script for %s\n", name );
|
||||
}
|
||||
|
||||
|
||||
/* NOTE:
|
||||
* This is actually rather a ridiculous thing to do, since headerDump
|
||||
* will incorrectly assume header types (RPMTAG_NAME, RPMTAG_RELEASE,
|
||||
* RPMTAG_SUMMARY). Since we're passing a signature, the correct types
|
||||
* would be (RPMSIGTAG_SIZE, RPMSIGTAG_PGP, and RPMSIGTAG_MD5).
|
||||
* TO FIX:
|
||||
* I think rpm's tagtable.c should define an rpmSigTable global var.
|
||||
* This is the perfect dual to rpmTagTable and would be passed to
|
||||
* headerDump when appropriate. It looks like someone intended to do
|
||||
* this at one time, but never finished it?
|
||||
*/
|
||||
|
||||
printf( "Dumping signatures...\n" );
|
||||
/* Use HEADER_DUMP_INLINE to include inline dumps of header items */
|
||||
headerDump( sig, stdout, HEADER_DUMP_INLINE, rpmTagTable );
|
||||
|
||||
rpmFreeSignature( sig );
|
||||
|
||||
printf( "Iterating through the header...\n" );
|
||||
iter = headerInitIterator( h );
|
||||
while( headerNextIterator( iter, &itertag, &type, &p, &count ) ) {
|
||||
/* printf( "itertag=%04d, type=%08lX, p=%08lX, c=%08lX\n",
|
||||
(int)itertag, (long)type, (long)p, (long)count ); */
|
||||
|
||||
switch( itertag ) {
|
||||
case RPMTAG_SUMMARY:
|
||||
if( type == RPM_I18NSTRING_TYPE ) {
|
||||
/* We'll only print out the first string if there's an array */
|
||||
printf( "The Summary: \"%s\"\n", *(char**)p );
|
||||
}
|
||||
if( type == RPM_STRING_TYPE ) {
|
||||
printf( "The Summary: \"%s\"\n", (char*)p );
|
||||
}
|
||||
break;
|
||||
case RPMTAG_FILENAMES:
|
||||
printf( "There are %d files in %s\n", count, name );
|
||||
break;
|
||||
}
|
||||
|
||||
/* rpmlib allocates a buffer to return these two values... */
|
||||
if( type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE ) {
|
||||
free( p );
|
||||
}
|
||||
}
|
||||
|
||||
headerFreeIterator( iter );
|
||||
headerFree( h );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<a href="Makefile">Makefile<a><p>
|
||||
<a href="dumprpm.c">dumprpm.c<a><p>
|
||||
<a href="README">README<a><p>
|
||||
<a href="showdb.c">showdb.c<a><p>
|
||||
<a href="showdb2.c">showdb2.c<a><p>
|
||||
<a href="string.txt">string.txt<a><p>
|
|
@ -0,0 +1,59 @@
|
|||
/* Example 2 from Maximum RPM book by Edward C. Bailey
|
||||
* Updated for 2.5.6 20 Mar 99 by Scott Bronson
|
||||
* Updated again for 3.0.3 4 Oct 99 by Scott Bronson
|
||||
*/
|
||||
|
||||
/* This iterates through all RPMs by name, using strcmp
|
||||
* to find the RPM named on the command line. See Example 3
|
||||
* for a much better way of doing this
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rpm/rpmlib.h>
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
Header h;
|
||||
int offset;
|
||||
int_32 type, count;
|
||||
char *name;
|
||||
rpmdb db;
|
||||
|
||||
rpmReadConfigFiles( NULL, NULL );
|
||||
|
||||
printf( "Calling rpmdbOpen\n" );
|
||||
if( rpmdbOpen( "", &db, O_RDONLY, 0644 ) != 0 ) {
|
||||
fprintf( stderr, "cannot open database!\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
printf( "rpmdbOpen done.\n" );
|
||||
|
||||
offset = rpmdbFirstRecNum( db );
|
||||
while( offset ) {
|
||||
h = rpmdbGetRecord( db, offset );
|
||||
if( !h ) {
|
||||
fprintf( stderr, "Header Read Failed!\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
headerGetEntry( h, RPMTAG_NAME, &type, (void**)&name, &count );
|
||||
if( strcmp(name,argv[1]) == 0 ) {
|
||||
headerDump( h, stdout, 1, rpmTagTable );
|
||||
}
|
||||
|
||||
headerFree( h );
|
||||
offset = rpmdbNextRecNum( db, offset );
|
||||
}
|
||||
|
||||
rpmdbClose( db );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* Example 3 from Maximum RPM book by Edward C. Bailey
|
||||
* Updated for 2.5.6 20 Mar 99 by Scott Bronson
|
||||
* Updated again for 3.0.3 4 Oct 99 by Scott Bronson
|
||||
*/
|
||||
|
||||
/* This uses rpmlib to search the database for the RPM
|
||||
* named on the command line.
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rpm/rpmlib.h>
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
Header h;
|
||||
int stat;
|
||||
rpmdb db;
|
||||
dbiIndexSet matches;
|
||||
|
||||
if( argc != 2 ) {
|
||||
fprintf( stderr, "usage: showdb2 <search term>\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
rpmReadConfigFiles( NULL, NULL );
|
||||
|
||||
if( rpmdbOpen( "", &db, O_RDONLY, 0644 ) != 0 ) {
|
||||
fprintf( stderr, "cannot open RPM database.\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
stat = rpmdbFindPackage( db, argv[1], &matches );
|
||||
printf( "Status is: %d\n", stat );
|
||||
if( stat == 0 ) {
|
||||
if( matches.count ) {
|
||||
printf( "Number of matches: %d\n", matches.count );
|
||||
h = rpmdbGetRecord( db, matches.recs[0].recOffset );
|
||||
if( h ) {
|
||||
headerDump( h, stdout, HEADER_DUMP_INLINE, rpmTagTable );
|
||||
headerFree( h );
|
||||
}
|
||||
}
|
||||
dbiFreeIndexRecord( matches );
|
||||
}
|
||||
|
||||
rpmdbClose( db );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
string.txt
|
||||
Scott Bronson
|
||||
bronson@trestle.com
|
||||
|
||||
|
||||
This describes the format of RPM_I18NSTRING_TYPE or RPM_STRING_ARRAY_TYPE,
|
||||
I could not find this documented anywhere except the source of rpmlib.
|
||||
|
||||
This memory block consists of count charptrs pointing to strings further
|
||||
along in the block. A brief example for a count of 2 (as returned by
|
||||
headerGetEntry), using typedef to illustrate the structure:
|
||||
|
||||
count = 2;
|
||||
typedef struct block { # beginning of malloc'd block
|
||||
char *c1 = &s1; # points to s1 below
|
||||
char *c2 = &s2; # points to s2 below
|
||||
char s1[] = "data for string 1";
|
||||
char s2[] = "data for string 2";
|
||||
} # end of malloc'd block
|
||||
|
||||
|
||||
And, if count were three, this would be the result:
|
||||
|
||||
count = 2;
|
||||
typedef struct block { # beginning of malloc'd block
|
||||
char *c1 = &s1; # points to s1 below
|
||||
char *c2 = &s2; # points to s2 below
|
||||
char *c3 = &s3; # points to s2 below
|
||||
char s1[] = "data for string 1";
|
||||
char s2[] = "data for string 2";
|
||||
char s3[] = "data for string 3";
|
||||
} # end of malloc'd block
|
||||
|
||||
|
||||
Therefore, to print out all the strings in one of these blocks in order...
|
||||
(p and count are values returned by rpmlib)
|
||||
|
||||
for( i=0; i<count; i++ ) {
|
||||
printf( "String %d: %s\n", i, *((char**)p+i) );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue