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:
jbj 2002-02-09 19:21:34 +00:00
parent 380b21d69e
commit 8ddeef05cd
7 changed files with 330 additions and 0 deletions

21
examples/Makefile Normal file
View File

@ -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

38
examples/README Normal file
View File

@ -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.

105
examples/dumprpm.c Normal file
View File

@ -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;
}

6
examples/index.html Normal file
View File

@ -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>

59
examples/showdb.c Normal file
View File

@ -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;
}

58
examples/showdb2.c Normal file
View File

@ -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;
}

43
examples/string.txt Normal file
View File

@ -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) );
}