Capture rpm-3.0.3 examples from "Maximum RPM".
authorjbj <devnull@localhost>
Sat, 9 Feb 2002 19:21:34 +0000 (19:21 +0000)
committerjbj <devnull@localhost>
Sat, 9 Feb 2002 19:21:34 +0000 (19:21 +0000)
CVS patchset: 5306
CVS date: 2002/02/09 19:21:34

examples/Makefile [new file with mode: 0644]
examples/README [new file with mode: 0644]
examples/dumprpm.c [new file with mode: 0644]
examples/index.html [new file with mode: 0644]
examples/showdb.c [new file with mode: 0644]
examples/showdb2.c [new file with mode: 0644]
examples/string.txt [new file with mode: 0644]

diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644 (file)
index 0000000..514f237
--- /dev/null
@@ -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
+
diff --git a/examples/README b/examples/README
new file mode 100644 (file)
index 0000000..196c897
--- /dev/null
@@ -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.
+
+
+
diff --git a/examples/dumprpm.c b/examples/dumprpm.c
new file mode 100644 (file)
index 0000000..637b7ad
--- /dev/null
@@ -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;
+}
+
+
diff --git a/examples/index.html b/examples/index.html
new file mode 100644 (file)
index 0000000..2df7800
--- /dev/null
@@ -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>
diff --git a/examples/showdb.c b/examples/showdb.c
new file mode 100644 (file)
index 0000000..def1ff2
--- /dev/null
@@ -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;
+}
+
diff --git a/examples/showdb2.c b/examples/showdb2.c
new file mode 100644 (file)
index 0000000..111d4f9
--- /dev/null
@@ -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;
+}
+
diff --git a/examples/string.txt b/examples/string.txt
new file mode 100644 (file)
index 0000000..1d22f0e
--- /dev/null
@@ -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) );
+      }
+
+