Initial revision
authorjbj <devnull@localhost>
Wed, 23 Oct 2002 15:39:41 +0000 (15:39 +0000)
committerjbj <devnull@localhost>
Wed, 23 Oct 2002 15:39:41 +0000 (15:39 +0000)
CVS patchset: 5803
CVS date: 2002/10/23 15:39:41

30 files changed:
lsbpkgchk/Licence [new file with mode: 0644]
lsbpkgchk/Makefile [new file with mode: 0644]
lsbpkgchk/README [new file with mode: 0644]
lsbpkgchk/src/tests/pkgchk/.cvsignore [new file with mode: 0644]
lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1 [new file with mode: 0644]
lsbpkgchk/src/tests/pkgchk/makefile [new file with mode: 0644]
lsbpkgchk/src/tests/pkgchk/pkgchk.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/.cvsignore [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/archive.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/fhs.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/hdr.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/idxtag.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/idxtbl.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/lead.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/makefile [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/md5.h [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/md5c.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/mktaghdr [new file with mode: 0755]
lsbpkgchk/src/tests/rpmchk/mktagtbl [new file with mode: 0755]
lsbpkgchk/src/tests/rpmchk/rpmchk.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/rpmchk.h [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/rpmtag.h [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/tagfuncs.h [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/test.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/util.c [new file with mode: 0644]
lsbpkgchk/src/tests/rpmchk/vals.c [new file with mode: 0644]
lsbpkgchk/src/tests/tetj/Makefile [new file with mode: 0644]
lsbpkgchk/src/tests/tetj/tetj.c [new file with mode: 0644]
lsbpkgchk/src/tests/tetj/tetj.h [new file with mode: 0644]
lsbpkgchk/src/tests/tetj/tetj.py [new file with mode: 0755]

diff --git a/lsbpkgchk/Licence b/lsbpkgchk/Licence
new file mode 100644 (file)
index 0000000..b5796cb
--- /dev/null
@@ -0,0 +1,71 @@
+
+
+SCCS: @(#)Licence       1.8 (99/01/18) lsbpkgchk Test Suite
+
+Preamble
+--------
+
+Testing is essential for proper development and maintenance
+of standards-based products.
+
+For buyers: adequate conformance testing leads to reduced integration
+costs and protection of investments in applications, software and people.
+
+For software developers: conformance testing of platforms and middleware
+greatly reduces the cost of developing and maintaining multi-platform
+application software.  
+
+For suppliers: In-depth testing increases customer
+satisfaction and keeps development and support costs in check. API
+conformance is highly measurable and suppliers who claim it must be able
+to substantiate that claim.
+
+
++++++++++++++LSBPKGCHK END USER LICENCE+++++++++++
+
+BY RETRIEVING THIS DISTRIBUTION OF LSBPKGCHK, YOU ARE CONSENTING TO BE BOUND BY
+THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THIS AGREEMENT,
+DO NOT INSTALL THE PRODUCT, AND DESTROY YOUR COPY.
+
+
+lsbpkgchk End User Licence
+_________________________________
+
+Copyright (c) 1991, 1992, 1997, 1998, 2000, 2001 X/Open Company Ltd. (X/Open)
+trading as The Open Group
+All rights reserved except as granted by this License.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the "Artistic License" which comes with this
+Kit, with the following modification:
+       a) "executable(s)" should be interpreted to include
+         "test case(s)"
+       b) if you wish to make changes as defined in clause 2 and 3, and
+        distribute a modified version of this package, then
+       clauses 3c and 4c are required
+       c) Clause 7 is rephrased as follows: "Subroutines supplied by you 
+       and linked into this Package shall not be considered part of this
+        Package".
+        
+
+X/OPEN, TRADING AS THE OPEN GROUP, DISCLAIMS ALL WARRANTIES WITH REGARD TO 
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS. IN NO EVENT SHALL X/OPEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+You should have received a copy of the Artistic License with this
+Kit, in the file named "Artistic".  If not, we'll be glad to provide one.
+
+
+Please send bug reports on lsbpkgchk to lsb-test@lists.linuxbase.org
+
+The latest version of this package can be obtained
+from ftp://ftp.freestandards.org/pub/lsb
+
+________________________________________________________________________
+
++++++++++++++END LSBPKGCHK END USER LICENCE+++++++++++
+
diff --git a/lsbpkgchk/Makefile b/lsbpkgchk/Makefile
new file mode 100644 (file)
index 0000000..4e55a20
--- /dev/null
@@ -0,0 +1,16 @@
+export BINDIR=/bin
+export MANDIR=/man
+export INSTALL_ROOT=/usr/local
+
+all:
+       cd src/tests/tetj && make 
+       cd src/tests/rpmchk && make 
+       cd src/tests/pkgchk && make 
+
+install:
+       cd src/tests/pkgchk && make install
+
+clean:
+       cd src/tests/pkgchk && make clean
+       cd src/tests/rpmchk && make clean
+       cd src/tests/tetj && make clean
diff --git a/lsbpkgchk/README b/lsbpkgchk/README
new file mode 100644 (file)
index 0000000..3f75f0d
--- /dev/null
@@ -0,0 +1,16 @@
+LSBAPPCHK
+---------
+
+lsbpkgchk is a program which forms part of a series of checks that a
+package is LSB compliant. It verifies a package and its contents conform
+to the LSV specification.
+
+Usage: lsbpkgchk file
+
+Note that the version number displayed refers to the version of the
+specification that lsbpkgchk was built for, not the version of
+lsbpkgchk itself.
+
+Please send any comments or feedback you may have to
+lsb-test@linuxbase.org
+
diff --git a/lsbpkgchk/src/tests/pkgchk/.cvsignore b/lsbpkgchk/src/tests/pkgchk/.cvsignore
new file mode 100644 (file)
index 0000000..23db96b
--- /dev/null
@@ -0,0 +1 @@
+pkgchk
diff --git a/lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1 b/lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1
new file mode 100644 (file)
index 0000000..8b18b7d
--- /dev/null
@@ -0,0 +1,25 @@
+.TH lsbpkgchk "1" "" "lsbpkgchk (LSB)" LSB
+.SH NAME
+lsbpkgchk \- check LSB conformance of a package
+.SH SYNOPSIS
+.B lsbpkgchk
+[\f-L \fIpathtolib\fR]... [\fIappname\fR]...
+.SH DESCRIPTION
+.PP
+Measure a package's conformance to the Linux Standard
+Base (LSB) specification. The format of the package, and the contents of the
+payload are checked.  Warnings are produced for anything that is used, but not
+contained in the LSB specification.
+.PP
+A journal file named journal.pkgchk> is created. It contains a record of the
+test results. You must have write access to the current working directory
+in order to run lsbpkgchk successfully.
+.SH "AUTHORS"
+The contributors to the Linux Standard Base.
+.SH "REPORTING BUGS"
+Report bugs to <lsb-test@linuxbase.org>.
+.SH "BUGS"
+Should be able to specify where to write the journal file.
+.SH "SEE ALSO"
+Linux Standard Base specification and other documents at
+http://www.linuxbase.org/
diff --git a/lsbpkgchk/src/tests/pkgchk/makefile b/lsbpkgchk/src/tests/pkgchk/makefile
new file mode 100644 (file)
index 0000000..6406cea
--- /dev/null
@@ -0,0 +1,24 @@
+LSBPKGCHK_VERSION=unofficial
+CFLAGS=-g -DLSBVERSION=\"$$LSBVERSION\" -DLSBPKGCHK_VERSION=\"$(LSBPKGCHK_VERSION)\" -Wall -I../rpmchk
+
+OBJS=pkgchk.o
+LIB=../rpmchk/librpmchk.a ../tetj/libtetj.a
+
+all: pkgchk
+
+pkgchk: $(OBJS) $(LIB)
+       $(CC) $(CFLAGS) -o pkgchk $(OBJS) $(LIB) -lz
+
+install:
+       install -d $(INSTALL_ROOT)/$(BINDIR)
+       install pkgchk $(INSTALL_ROOT)/$(BINDIR)/lsbpkgchk
+       install -d $(INSTALL_ROOT)/$(MANDIR)/man1
+       install lsbpkgchk.1 $(INSTALL_ROOT)/$(MANDIR)/man1/lsbpkgchk.1
+
+clean:
+       rm -f $(OBJS) pkgchk
+
+distclean: clean
+
+test_journal: test_journal.o tetj.o
+       $(CC) $(CFLAGS) -o test_journal test_journal.o tetj.o
diff --git a/lsbpkgchk/src/tests/pkgchk/pkgchk.c b/lsbpkgchk/src/tests/pkgchk/pkgchk.c
new file mode 100644 (file)
index 0000000..eb66cd7
--- /dev/null
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <limits.h>
+#include "../tetj/tetj.h"
+#include "rpmchk.h"
+
+void usage(char *progname)
+{
+  fprintf(stderr,"Usage: %s rpmname\n",progname);
+  exit(1);
+}
+
+char *
+concat_string(char *input, char *addition)
+{
+  char *tmp;
+  if (input)
+  {
+    tmp = realloc(input, strlen(input)+strlen(addition)+1);
+    if (!tmp) abort();
+    return strcat(tmp, addition);
+  }
+  else
+  {
+    return strdup(addition);
+  }
+}
+
+/* Real CVS revision number so we can strings it from
+   the binary if necessary */
+static const char * __attribute((unused)) pkgchk_revision = "Revision: 1.2 ";
+
+int
+main(int argc, char *argv[])
+{
+  signed char  c,*ptr;
+  struct tetj_handle *journal;
+  char *command_line = NULL;
+  int i;
+#define TMP_STRING_SIZE (PATH_MAX+20)
+  char tmp_string[TMP_STRING_SIZE+1];
+  RpmFile *rpmfile;
+
+  printf("%s for LSB Specification " LSBVERSION " \n", argv[0]);
+
+  for (i=0; i<argc; i++)
+  {
+    command_line = concat_string(command_line, argv[i]);
+    command_line = concat_string(command_line, " ");
+  }
+
+  if( argc != 2 ) {
+    fprintf(stderr, "%s: bad argument count %d\n", argv[0], argc );
+    usage(argv[0]);
+    }
+
+  if( (ptr=getenv("RPMCHK_DEBUG")) != NULL ) {
+    rpmchkdebug=strtod(ptr,NULL);
+    if( rpmchkdebug&DEBUG_ENV_OVERRIDES )
+      fprintf(stderr,"rpmchk debug set to 0x%x\n", rpmchkdebug );
+    }
+
+
+  if( (rpmfile = OpenRpmFile(argv[1])) == NULL ) {
+    fprintf(stderr, "%s: Unable to open file %s\n", argv[0], argv[1] );
+    usage(argv[0]);
+    }
+
+  /* Start journal logging */
+  snprintf(tmp_string, TMP_STRING_SIZE, "journal.pkgchk.%s", 
+           basename(argv[optind]));
+  if (tetj_start_journal(tmp_string, &journal, command_line)!=0)
+  {
+    perror("Could not open journal file");
+    exit(1);
+  }
+
+  /* Log version number for lsbpkgchk package */
+  snprintf(tmp_string, TMP_STRING_SIZE, "VSX_NAME=lsbpkgchk " LSBPKGCHK_VERSION);
+  tetj_add_config(journal, tmp_string);
+
+  checkRpm(rpmfile, journal);
+
+  tetj_close_journal(journal);
+  exit(0);
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/.cvsignore b/lsbpkgchk/src/tests/rpmchk/.cvsignore
new file mode 100644 (file)
index 0000000..9daeafb
--- /dev/null
@@ -0,0 +1 @@
+test
diff --git a/lsbpkgchk/src/tests/rpmchk/archive.c b/lsbpkgchk/src/tests/rpmchk/archive.c
new file mode 100644 (file)
index 0000000..d178c5d
--- /dev/null
@@ -0,0 +1,333 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <zlib.h>
+#include <cpio.h>
+#include "rpmchk.h"
+#include "md5.h"
+#include "tagfuncs.h"
+#include "../tetj/tetj.h"
+
+MD5_CTX        md5ctx;
+unsigned char  fbuf[1024];
+
+void
+checkRpmArchive(RpmFile *file1, struct tetj_handle *journal)
+{
+#define TMP_STRING_SIZE (400)
+char tmp_string[TMP_STRING_SIZE+1];
+unsigned char  md5sum[17],md5str[33];
+unsigned char  *fmd5=filemd5s,*flinktos=filelinktos;
+gzFile *zfile;
+RpmArchiveHeader ahdr;
+int    startoffset,endoffset;
+int    fileindex=0;
+int    filesizesum=0;
+
+file1->archive=(caddr_t)file1->nexthdr;
+
+/*
+fprintf(stderr,"checkRpmArchive() archive=%x\n", (int)file1->archive );
+*/
+
+/* Check the RpmHeader magic value */
+tetj_tp_count++;
+tetj_purpose_start(journal, tetj_activity_count, tetj_tp_count, "Check magic value");
+if( !( file1->archive[0]==(char)0x1f
+    && file1->archive[1]==(char)0x8b) ) {
+        snprintf( tmp_string, TMP_STRING_SIZE,
+    "checkRpmArchive: magic isn't expected value 0x1f8b, found %x%x instead\n",
+            (unsigned int)file1->archive[0], (unsigned int)file1->archive[1]); 
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count,
+                                                       0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+} else {
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_PASS); 
+}
+tetj_purpose_end(journal, tetj_activity_count, tetj_tp_count); 
+
+/*
+ * Now we need to set up zlib so that we can read/decompres the archive.
+ */
+
+if( lseek(file1->fd, (file1->archive-file1->addr), SEEK_SET) < 0 ) {
+        snprintf( tmp_string, TMP_STRING_SIZE,
+    "checkRpmArchive: Unable to seek to start of archive\n");
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count,
+                                                       0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+       return;
+       }
+
+if( (zfile=gzdopen(file1->fd,"r")) == NULL ) {
+        snprintf( tmp_string, TMP_STRING_SIZE,
+    "checkRpmArchive: Unable to open compressed archive\n");
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count,
+                                                       0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+       return;
+       }
+
+startoffset=gztell(zfile);
+/*
+ * The archive is really a cpio format file, so start reading records
+ * and examining them.
+ */
+
+while( !gzeof(zfile) ) {
+       char    *fptr,*fmt,filename[PATH_MAX+1],tagfilename[PATH_MAX+1];
+       char    num[9];
+       int     size,mode,devmaj,devmin,flink,fino;
+       time_t  ftime;
+
+       gzread(zfile, &ahdr, sizeof(ahdr) );
+/*
+       printf("***************************\n");
+       printf("Magic: %6.6s\n", ahdr.c_magic );
+       printf("ino: %8.8s\n", ahdr.c_ino );
+       printf("Mode: %8.8s\n", ahdr.c_mode );
+       printf("Rdev: %8.8s,%8.8s\n", ahdr.c_rdevmajor,ahdr.c_rdevminor );
+       printf("mtime: %8.8s\n", ahdr.c_mtime );
+       printf("nlink: %8.8s\n", ahdr.c_nlink );
+       printf("filesize: %8.8s\n", ahdr.c_filesize );
+       printf("namesize: %8.8s\n", ahdr.c_namesize );
+       printf("UID: %8.8s\n", ahdr.c_uid );
+       printf("GID: %8.8s\n", ahdr.c_gid );
+*/
+       if( !(strncmp(ahdr.c_magic,"070701",6) == 0) ) {
+               snprintf( tmp_string, TMP_STRING_SIZE,
+               "checkRpmArchive: Archive record has wrong magic %6.6s instead of 070701",
+               ahdr.c_magic);
+               fprintf(stderr, "%s\n", tmp_string);
+               tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count,
+                                                       0, 0, 0, tmp_string);
+               tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+       }
+       /* Read in the filename */
+       memcpy(num,ahdr.c_namesize,8);
+       num[8]=0; /* NULL terminate the namesize */
+       size=strtol(num,NULL,16);
+       gzread(zfile, filename, size );
+       /*
+        * Check/fix padding here - the amount of space used for the header
+        * is rounded up to the long-word (32 its), so 1-3 bytes of padding
+        * may need to be skipped.
+        */
+       size=gztell(zfile);
+       size%=4;
+       size=4-size;
+       size%=4;
+       //printf("padding %d\n", size);
+       gzseek(zfile,size,SEEK_CUR);
+
+       /*
+        * Check for the end of the archive
+        */
+       if( strcmp(filename,"TRAILER!!!") == 0 ) {
+               /* End of archive */
+               break;
+               }
+
+       /* Skip the file contents */
+       memcpy(num,ahdr.c_filesize,8);
+       num[8]=0;
+       size=strtol(num,NULL,16);
+
+       /* Get the mode so we can idendify directories */
+       memcpy(num,ahdr.c_mode,8);
+       num[8]=0;
+       mode=strtol(num,NULL,16);
+
+       /*
+        * Check the file name against the RPMTAG_DIRNAME, RPMTAG_DIRINDEXES,
+        * RPMTAG_BASENAME values.
+        */
+
+       if(hasPayloadFilesHavePrefix) {
+               fmt=".%s%s";
+       } else {
+               fmt="%s%s";
+       }
+       if( dirindicies[fileindex] <= numdirnames ) {
+               /*
+               fprintf(stderr,"dirindex: %x\n", dirindicies[fileindex]);
+               fprintf(stderr,"dirname: %s\n",
+                                       dirnames[dirindicies[fileindex]]);
+               fprintf(stderr,"basename: %s\n", basenames[fileindex]);
+               */
+               sprintf(tagfilename,fmt,
+                       dirnames[dirindicies[fileindex]],basenames[fileindex]);
+
+               if( strcmp(filename,tagfilename) != 0 ) {
+                       fprintf(stderr,
+                   "Payload filename %s doesn't match RPMTAG based name %s\n",
+                       filename, tagfilename);
+               }
+       } else {
+               fprintf(stderr,"dirindex out of range!!!\n");
+       }
+
+       /*
+        * Check the file size against the RPMTAG_FILESIZES value
+        */
+
+       /* Directories have no size, but RPMTAG_FILESIZES sez 1024 */
+       if( S_ISREG(mode) && (size != filesizes[fileindex]) ) {
+               fprintf(stderr,"Filesize (%d) for %s not that same a specified in RPMTAG_FILESIZES (%d)\n", size, filename, filesizes[fileindex] );
+       }
+       filesizesum+=size;
+
+       /*
+        * Check the file modes against the RPMTAG_FILEMODES value
+        */
+
+       if( (mode != filemodes[fileindex]) ) {
+               fprintf(stderr,"Filemode  (%o) for %s not that same a specified in RPMTAG_FILEMODES (%o)\n", mode, filename, filemodes[fileindex] );
+       }
+
+       /*
+        * Check the file dev against the RPMTAG_FILEDEVICES value
+        */
+
+       memcpy(num,ahdr.c_devmajor,8);
+       num[8]=0;
+       devmaj=strtol(num,NULL,16);
+
+       memcpy(num,ahdr.c_devminor,8);
+       num[8]=0;
+       devmin=strtol(num,NULL,16);
+
+       if( (makedev(devmaj,devmin) != filedevs[fileindex]) ) {
+               fprintf(stderr,"File dev (%x) for %s not that same a specified in RPMTAG_FILEDEVICES (%x)\n", makedev(devmaj,devmin), filename, filedevs[fileindex] );
+       }
+
+       /*
+        * Check the file rdev against the RPMTAG_FILERDEVS value
+        */
+
+       memcpy(num,ahdr.c_rdevmajor,8);
+       num[8]=0;
+       devmaj=strtol(num,NULL,16);
+
+       memcpy(num,ahdr.c_rdevminor,8);
+       num[8]=0;
+       devmin=strtol(num,NULL,16);
+
+       if( (makedev(devmaj,devmin) != filerdevs[fileindex]) ) {
+               fprintf(stderr,"File rdev (%x) for %s not that same a specified in RPMTAG_FILERDEVS (%x)\n", makedev(devmaj,devmin), filename, filerdevs[fileindex] );
+       }
+
+       /*
+        * Check the file modes against the RPMTAG_FILEMTIMES value
+        */
+
+       memcpy(num,ahdr.c_mtime,8);
+       num[8]=0;
+       ftime=strtol(num,NULL,16);
+
+       if( (ftime != filetimes[fileindex]) ) {
+               fprintf(stderr,"File time  (%x) for %s not that same a specified in RPMTAG_FILEMTIMES (%x)\n", (unsigned int)ftime, filename, filetimes[fileindex] );
+       }
+
+       /*
+        * Check the file modes against the RPMTAG_FILEINODES value
+        */
+
+       memcpy(num,ahdr.c_ino,8);
+       num[8]=0;
+       fino=strtol(num,NULL,16);
+
+       if( (fino != fileinodes[fileindex]) ) {
+               fprintf(stderr,"File inode  (%x) for %s not that same a specified in RPMTAG_FILEINODES (%x)\n", (unsigned int)fino, filename, fileinodes[fileindex] );
+       }
+
+       /*
+        * Check the file modes against the RPMTAG_FILEMD5S value
+        */
+
+       if( S_ISREG(mode) ) {
+               MD5Init(&md5ctx);
+               while ( size>0 ) {
+                       gzread(zfile,fbuf,size>1024?1024:size);
+                       MD5Update(&md5ctx,fbuf,size>1024?1024:size);
+                       size-=1024;
+                       }
+               MD5Final(md5sum,&md5ctx);
+               sprintf(md5str,"%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
+                       md5sum[0], md5sum[1], md5sum[2], md5sum[3],
+                       md5sum[4], md5sum[5], md5sum[6], md5sum[7],
+                       md5sum[8], md5sum[9], md5sum[10], md5sum[11],
+                       md5sum[12], md5sum[13], md5sum[14], md5sum[15] );
+
+               if( strncmp(fmd5,md5str,16) != 0 ) {
+                       fprintf(stderr,"File MD5 (%s) for %s does not match value in RPMTAG_FILEMD5S (%s)\n", md5str, filename, fmd5 );
+                       }
+       }
+       fmd5+=strlen(fmd5)+1;
+
+       /*
+        * Check the file modes against the RPMTAG_FILELINKTOS value
+        */
+
+       memcpy(num,ahdr.c_nlink,8);
+       num[8]=0;
+       flink=strtol(num,NULL,16);
+
+       if( S_ISREG(mode) && flink>1 && !*flinktos ) {
+               fprintf(stderr,"File link expected, but no FILELINKTOS entry\n");
+       }
+       if( S_ISREG(mode) && flink==1 && *flinktos ) {
+               fprintf(stderr,"File link not expected, but FILELINKTOS present\n");
+       }
+       filelinktos+=strlen(filelinktos)+1;
+
+
+       /*
+        * Check/fix padding here - the amount of space used for the file
+        * is rounded up to the long-word (32 its), so 1-3 bytes of padding
+        * may need to be skipped.
+        */
+       size=gztell(zfile);
+       //printf("offset %x\n", size);
+       size%=4;
+       size=4-size;
+       size%=4;
+       //printf("padding %d\n", size);
+       gzseek(zfile,size,SEEK_CUR);
+
+
+       /* Now, check the filename */
+       if( filename[0] == '.' && filename[1] == '/' )
+               fptr=&filename[1];
+       else
+               fptr=&filename[0];
+       checkRpmArchiveFilename(fptr, journal);
+
+       fileindex++;
+       }
+
+endoffset=gztell(zfile);
+
+/*
+fprintf(stderr,"%d bytes in uncompressed archive\n", endoffset-startoffset);
+*/
+if( endoffset-startoffset != archivesize ) {
+               fprintf(stderr,"Archive size (%d) does ",endoffset-startoffset);
+               fprintf(stderr,"not match the value in RPMTAG_ARCHIVESIZE (%d)\n",
+                                                       archivesize );
+       }
+
+/*
+fprintf(stderr,"%d bytes in archive files\n", filesizesum);
+*/
+if( filesizesum != rpmtagsize ) {
+               fprintf(stderr,"Sum of file sizes (%d) does ",filesizesum);
+               fprintf(stderr,"not match the value in RPMTAG_SIZE (%d)\n",
+                                                       rpmtagsize );
+       }
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/fhs.c b/lsbpkgchk/src/tests/rpmchk/fhs.c
new file mode 100644 (file)
index 0000000..d607e9f
--- /dev/null
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <zlib.h>
+#include <cpio.h>
+#include "rpmchk.h"
+#include "tagfuncs.h"
+#include "../tetj/tetj.h"
+
+/*
+ * This file is used to compare a filename to the FHS/LSB to determine if
+ * it is a valid path for an application to be providing.
+ */
+
+void
+checkRpmArchiveFilename(char *filename, struct tetj_handle *journal)
+{
+#define TMP_STRING_SIZE (400)
+char tmp_string[TMP_STRING_SIZE+1];
+
+/* Check the RpmHeader magic value */
+tetj_tp_count++;
+tetj_purpose_start(journal, tetj_activity_count, tetj_tp_count, "Check filename");
+if( strncmp(filename,"/opt",4) != 0 ) {
+        snprintf( tmp_string, TMP_STRING_SIZE,
+    "checkRpmArchiveFilename: file %s not placed under /opt\n", filename );
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count,
+                                                       0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+} else {
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_PASS); 
+}
+tetj_purpose_end(journal, tetj_activity_count, tetj_tp_count); 
+
+return;
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/hdr.c b/lsbpkgchk/src/tests/rpmchk/hdr.c
new file mode 100644 (file)
index 0000000..525cba3
--- /dev/null
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <string.h>
+#include "rpmchk.h"
+#include "tagfuncs.h"
+#include "../tetj/tetj.h"
+
+void
+checkRpmHdr(RpmFile *file1, struct tetj_handle *journal)
+{
+#define TMP_STRING_SIZE (400)
+char tmp_string[TMP_STRING_SIZE+1];
+RpmHeader      *hdr;
+RpmHdrIndex    *hindex;
+
+hdr=(RpmHeader *)file1->nexthdr;
+hindex=(RpmHdrIndex *)(hdr+1);
+
+/*
+fprintf(stderr,"checkRpmHdr() hdr=%x\n", hdr );
+*/
+
+/* Check the RpmHeader magic value */
+tetj_tp_count++;
+tetj_purpose_start(journal, tetj_activity_count, tetj_tp_count, "Check magic value");
+if(strncmp(hdr->magic,RPMHDRMAG,SRPMHDRMAG)) {
+        snprintf( tmp_string, TMP_STRING_SIZE, "compareRpmHeader: magic isn't expected value RPMHDRMAG, found %x %x %x instead\n", hdr->magic[0], hdr->magic[1], hdr->magic[2]); 
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count, 0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+} else {
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_PASS); 
+}
+tetj_purpose_end(journal, tetj_activity_count, tetj_tp_count); 
+
+/* Check the RpmHeader version */
+tetj_tp_count++;
+tetj_purpose_start(journal, tetj_activity_count, tetj_tp_count, "Check magic value");
+if(hdr->version != RPMHDRVER ) {
+        snprintf( tmp_string, TMP_STRING_SIZE, "compareRpmHeader: magic isn't expected value RPMHDRMAG, found %x %x %x instead\n", hdr->magic[0], hdr->magic[1], hdr->magic[2]); 
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count, 0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+} else {
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_PASS); 
+}
+tetj_purpose_end(journal, tetj_activity_count, tetj_tp_count); 
+
+}
+
+void
+checkRpmSignature(RpmFile *file1, struct tetj_handle *journal)
+{
+RpmHeader      *hdr;
+RpmHdrIndex    *hindex;
+int    nindex;
+
+hdr=(RpmHeader *)file1->nexthdr;
+hindex=(RpmHdrIndex *)(hdr+1);
+nindex=ntohl(hdr->nindex);
+file1->storeaddr=(((char *)hdr)+sizeof(RpmHeader)+(nindex*sizeof(RpmHdrIndex)));
+file1->header=(RpmHeader *)((char *)file1->storeaddr+
+               ntohl(hindex->offset)+ntohl(hindex->count));
+
+/*
+fprintf(stderr,"Signature has %d indicies with %x bytes of store at %x\n",
+                       nindex, ntohl(hdr->hsize),file1->storeaddr);
+*/
+
+checkRpmHdr(file1, journal);
+checkRpmIdx(file1, hindex, SigTags, numSigIdxTags, journal);
+
+file1->nexthdr=(RpmHeader *)((char *)file1->storeaddr+
+               ntohl(hindex->offset)+ntohl(hindex->count));
+}
+
+void
+checkRpmHeader(RpmFile *file1, struct tetj_handle *journal)
+{
+RpmHeader      *hdr;
+RpmHdrIndex    *hindex;
+int    nindex;
+
+hdr=(RpmHeader *)file1->nexthdr;
+hindex=(RpmHdrIndex *)(hdr+1);
+nindex=ntohl(hdr->nindex);
+file1->storeaddr=(((char *)hdr)+sizeof(RpmHeader)+(nindex*sizeof(RpmHdrIndex)));
+
+/*
+fprintf(stderr,"Header has %d indicies with %x bytes of store at %x\n",
+                       nindex, ntohl(hdr->hsize),file1->storeaddr);
+*/
+
+checkRpmHdr(file1, journal);
+checkRpmIdx(file1, hindex, HdrTags, numHdrIdxTags, journal);
+
+file1->nexthdr=(RpmHeader *)((char *)file1->storeaddr+
+               ntohl(hindex->offset)+ntohl(hindex->count));
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/idxtag.c b/lsbpkgchk/src/tests/rpmchk/idxtag.c
new file mode 100644 (file)
index 0000000..0b81689
--- /dev/null
@@ -0,0 +1,1174 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include "rpmchk.h"
+#include "md5.h"
+#include "tagfuncs.h"
+#include "../tetj/tetj.h"
+
+MD5_CTX md5ctx;
+
+void
+checkRpmIdx(RpmFile *file1, RpmHdrIndex *hidx, RpmIdxTagFuncRec Tags[],
+                               int numtags, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            i,j,nindex,tag,type,count;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+for(i=0;i<nindex;i++) {
+       tag=ntohl(hidx[i].tag);
+       type=ntohl(hidx[i].type);
+       count=ntohl(hidx[i].count);
+       for(j=0;j<numtags;j++)
+               if( Tags[j].tag == tag ) {
+                       Tags[j].status=Seen;
+                       /* Check the type */
+                       if( Tags[j].type != type ) {
+                               fprintf(stderr, "Type for Index %s does not match. ", Tags[j].name );
+                               fprintf(stderr, "Found %d but expecting %d.\n", type, Tags[j].type );
+                       }
+                       /* Check the count */
+                       if( Tags[j].count && Tags[j].count != count ) {
+                               fprintf(stderr, "Count for Index %s does not match. ", Tags[j].name );
+                               fprintf(stderr, "Found %d but expecting %d.\n", count, Tags[j].count );
+                       }
+                       if( rpmchkdebug&DEBUG_TRACE_TAGS )
+                               fprintf(stderr,"Found index %s\n",Tags[j].name);
+                       Tags[j].func(file1, &hidx[i], journal);
+                       break;
+                       }
+       if( j == numtags ) {
+               fprintf(stderr,"checkRpmIdx() unexpected Index tag=%d type=%d offset=%x count=%x\n",
+                               ntohl(hidx[i].tag), ntohl(hidx[i].type),
+                               ntohl(hidx[i].offset),ntohl(hidx[i].count));
+               /* checkRpmIdxUNKNOWN(file1, &hidx[i], journal); */
+               }
+       }
+
+/* Go through the table, and make sure that the required Indices were seen */
+}
+
+/*
+ * These functions correspond to the header private tag values
+ */
+
+void
+checkRpmIdxHEADERSIGNATURES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            hoffset;
+RpmHdrIndex    *sigidx;
+
+/* This Index contains a copy of the Header. Just check out the first entry */
+
+hoffset=ntohl(hidx->offset);
+sigidx=(RpmHdrIndex *)(file1->storeaddr+hoffset);
+
+if( ntohl(sigidx->tag) != RPMTAG_HEADERSIGNATURES ) {
+       fprintf(stderr,
+       "Tag value in RPMTAG_HEADERSIGNATURES data is not RPMTAG_HEADERSIGNATURES\n");
+       }
+if( ntohl(sigidx->type) != BIN ) {
+       fprintf(stderr, "Type value in RPMTAG_HEADERSIGNATURES data is not BIN\n");
+       }
+if( ntohl(sigidx->count) != sizeof(RpmHdrIndex) ) {
+       fprintf(stderr,
+     "Count value in RPMTAG_HEADERSIGNATURES data is not sizeof(RpmHdrIndex)\n");
+       }
+sigdata=(char *)(((char *)sigidx)+ntohl(sigidx->offset));
+
+}
+
+void
+checkRpmIdxHEADERIMMUTABLE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            hoffset;
+RpmHdrIndex    *imuidx;
+RpmHeader      *hdrdata;
+
+hoffset=ntohl(hidx->offset);
+imuidx=(RpmHdrIndex *)(file1->storeaddr+hoffset);
+hdrdata=(RpmHeader *)(((char *)imuidx)+ntohl(imuidx->offset));
+
+if( ntohl(imuidx->tag) != RPMTAG_HEADERIMMUTABLE ) {
+       fprintf(stderr,
+       "Tag value in RPMTAG_HEADERIMMUTABLE data is not RPMTAG_HEADERIMMUTABLE\n");
+       }
+
+if( ntohl(imuidx->type) != BIN ) {
+       fprintf(stderr, "Type value in RPMTAG_HEADERIMMUTABLE data is not BIN\n");
+       }
+
+if( ntohl(imuidx->count) != sizeof(RpmHdrIndex) ) {
+       fprintf(stderr,
+     "Count value in RPMTAG_HEADERIMMUTABLE data is not sizeof(RpmHdrIndex)\n");
+       }
+
+fprintf(stderr,"checkRpmIdxHEADERIMMUTABLE() Not yet checking contents\n");
+
+}
+
+void
+checkRpmIdxHDRREGIONS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+fprintf(stderr,"checkRpmIdxHDRREGIONS() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+void
+checkRpmIdxHEADERI18NTABLE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            hoffset,i;
+char           *string;
+hoffset=ntohl(hidx->offset);
+string=file1->storeaddr+hoffset;
+
+for(i=0;i<ntohl(hidx->count);i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Locales found: %s\n",string);
+       string+=strlen(string);
+       string++; /*skip over the NULL to get to the next string */
+       }
+}
+
+/*
+ * These values don't really show up as Indicies.
+ */
+void
+checkRpmIdxHEADERSIGBASE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+fprintf(stderr,"checkRpmIdxHEADERSIGBASE() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+/*
+ * These functions correspond to the tag values for a Signature
+ */
+
+void
+checkRpmIdxSIGSIZE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            hoffset;
+unsigned int   *value,size;
+
+hoffset=ntohl(hidx->offset);
+value=(int *)(file1->storeaddr+hoffset);
+sigsize=htonl(*value);
+size=file1->size-((char *)file1->header-file1->addr);
+
+if( sigsize != size ) {
+       fprintf(stderr,"SIGTAG_SIZE value %d doesn't match expected value %d\n",
+                               sigsize,        size );
+       }
+
+}
+
+void
+checkRpmIdxMD5(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            hoffset;
+unsigned char  *md5hdr,md5sum[16];
+
+hoffset=ntohl(hidx->offset);
+md5hdr=(char *)(file1->storeaddr+hoffset);
+
+MD5Init(&md5ctx);
+MD5Update(&md5ctx,file1->header,sigsize);
+MD5Final(md5sum,&md5ctx);
+
+if( memcmp(md5hdr,md5sum,16) != 0 ) {
+       fprintf(stderr,
+               "SIGTAG_MD5 calculated value doesn't match expected value\n");
+       }
+}
+
+#if 0
+/* We hope to never see these */
+void
+checkRpmIdxGPG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+fprintf(stderr,"checkRpmIdxGPG() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+void
+checkRpmIdxPGP5(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+fprintf(stderr,"checkRpmIdxPGP5() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+void
+checkRpmIdxPGP(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+fprintf(stderr,"checkRpmIdxPGP() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+#endif
+
+void
+checkRpmIdxSHA1HEADER(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            hoffset;
+unsigned char  *shadata;
+
+hoffset=ntohl(hidx->offset);
+shadata=file1->storeaddr+hoffset;
+
+if( shadata != sigdata ) {
+       fprintf(stderr,"Location of SHA1 signature (%x) ",
+                                               (unsigned int)shadata );
+       fprintf(stderr,"doesn't match location set in HDRSIGNATURES(%x)\n",
+                                               (unsigned int)sigdata);
+       }
+fprintf(stderr,"checkRpmIdxSHA1HEADER() Not yet checking SHA1 contents\n");
+}
+
+/*
+ * These functions are for the normal RPM tags.
+ */
+
+#if 0
+/* Don't seem to need these either */
+void
+checkRpmIdxSIGNATURES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+
+fprintf(stderr,"checkRpmIdxSIGNATURES() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+void
+checkRpmIdxIMMUTABLE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+int            nindex;
+RpmHeader      *hdr;
+
+hdr=(RpmHeader *)file1->nexthdr;
+nindex=ntohl(hdr->nindex);
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+fprintf(stderr,"checkRpmIdxIMMUTABLE() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+void
+checkRpmIdxUNKNOWN(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    htag, htype, hoffset, hcount;
+/*
+char   *data=(char *)hidx;
+*/
+
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+fprintf(stderr,"checkRpmIdxUNKNOWN() tag=%d (%x) type=%d offset=%x count=%x\n",
+                                       htag,htag,htype,hoffset,hcount);
+/*
+fprintf(stderr,"%2.2x %2.2x %2.2x %2.2x\n",
+                               data[0], data[1], data[2], data[3]);
+fprintf(stderr,"%2.2x %2.2x %2.2x %2.2x\n",
+                               data[4], data[5], data[6], data[7]);
+fprintf(stderr,"%2.2x %2.2x %2.2x %2.2x\n",
+                               data[8], data[9], data[10], data[11]);
+fprintf(stderr,"%2.2x %2.2x %2.2x %2.2x\n",
+                               data[12], data[13], data[14], data[15]);
+*/
+}
+
+void
+checkRpmIdxSERIAL(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int            htag, htype, hoffset, hcount;
+
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+fprintf(stderr,"checkRpmIdxSERIAL() type=%d offset=%x count=%x\n",
+                                               htype,hoffset,hcount);
+}
+
+#endif
+
+void
+checkRpmIdxNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+
+hoffset=ntohl(hidx->offset);
+pkgname=file1->storeaddr+hoffset;
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package name: %s\n",pkgname);
+}
+
+void
+checkRpmIdxVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Version: %s\n",name);
+}
+
+void
+checkRpmIdxRELEASE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Release: %s\n",name);
+}
+
+void
+checkRpmIdxSUMMARY(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset,i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+for(i=0;i<ntohl(hidx->count);i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Package Summary: %s\n",name);
+       name+=strlen(name);
+       name++; /*skip over the NULL to get to the next string */
+       }
+}
+
+void
+checkRpmIdxDESCRIPTION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset,i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+for(i=0;i<ntohl(hidx->count);i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Package Description: %s\n",name);
+       name+=strlen(name);
+       name++; /*skip over the NULL to get to the next string */
+       }
+}
+
+void
+checkRpmIdxBUILDTIME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+unsigned int   *name;
+time_t btime;
+
+hoffset=ntohl(hidx->offset);
+name=(unsigned int *)(file1->storeaddr+hoffset);
+btime=htonl(*name);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Buildtime: %s",ctime(&btime));
+}
+
+void
+checkRpmIdxBUILDHOST(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Buildhost: %s\n",name);
+}
+
+void
+checkRpmIdxSIZE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+int    *sizep;
+
+hoffset=ntohl(hidx->offset);
+sizep=(int *)(file1->storeaddr+hoffset);
+rpmtagsize=htonl(*sizep);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Size: %d.\n",rpmtagsize);
+}
+
+void
+checkRpmIdxLICENSE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package License: %s\n",name);
+}
+
+void
+checkRpmIdxGROUP(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Group: %s\n",name);
+}
+
+void
+checkRpmIdxOS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( strcmp(name,validos) != 0 ) {
+       fprintf(stderr,"Incorrect RPMTAG_OS: expecting %s but found %s\n",
+                                               validos,                name);
+       }
+}
+
+void
+checkRpmIdxARCH(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( strcmp(name,architecture) != 0 ) {
+       fprintf(stderr,"Incorrect RPMTAG_ARCH: expecting %s but found %s\n",
+                                               architecture,           name);
+       }
+}
+
+void
+checkRpmIdxFILESIZES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hcount,hoffset, i;
+
+hcount=ntohl(hidx->count);
+hoffset=ntohl(hidx->offset);
+filesizes=(int *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       filesizes[i]=htonl(filesizes[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Filesize: %d\n",filesizes[i]);
+       }
+}
+
+void
+checkRpmIdxFILEMODES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount,i;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filemodes=(short *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       filemodes[i]=htons(filemodes[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Filemodes: %x\n",filemodes[i]);
+       }
+}
+
+void
+checkRpmIdxFILERDEVS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount,i;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filerdevs=(short *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       filerdevs[i]=htons(filerdevs[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Filerdevs: %x\n",filerdevs[i]);
+       }
+}
+
+void
+checkRpmIdxFILEMTIMES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount,i;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filetimes=(int *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       filetimes[i]=htonl(filetimes[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Filetime: %d\n",filetimes[i]);
+       }
+}
+
+void
+checkRpmIdxFILEMD5S(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filemd5s=(char *)(file1->storeaddr+hoffset);
+name=filemd5s;
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File MD5: %s\n",name);
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxFILELINKTOS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filelinktos=(char *)(file1->storeaddr+hoffset);
+name=filelinktos;
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File linkto: %s\n",name);
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxFILEFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount,i;
+unsigned int   *fflags;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+fflags=(int *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       fflags[i]=htonl(fflags[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File flags: %x\n",fflags[i]);
+       fprintf(stderr,"File flags not checked: %x\n",fflags[i]);
+       }
+}
+
+void
+checkRpmIdxFILEUSERNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+fileusernames=(char *)(file1->storeaddr+hoffset);
+name=fileusernames;
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File username: %s\n",name);
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxFILEGROUPNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filegroupnames=(char *)(file1->storeaddr+hoffset);
+name=filegroupnames;
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File groupname: %s\n",name);
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxSOURCERPM(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"RPMTAG_SOURCERPM: %s\n", name);
+}
+
+void
+checkRpmIdxFILEVERIFYFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+unsigned int   *flagp;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+flagp=(int *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       flagp[i]=htonl(flagp[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File Verify Flag: %x\n",flagp[i]);
+       fprintf(stderr,"File Verify Flag not checked: %x\n",flagp[i]);
+       }
+}
+
+void
+checkRpmIdxARCHIVESIZE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+uint32_t *sizep;
+
+hoffset=ntohl(hidx->offset);
+sizep=(uint32_t *)(file1->storeaddr+hoffset);
+archivesize=htonl(*sizep);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Package Size: %d.\n",archivesize);
+}
+
+void
+checkRpmIdxPROVIDENAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    htag, htype, hoffset, hcount;
+char   *name;
+
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=file1->storeaddr+hoffset;
+fprintf(stderr,"checkRpmIdxPROVIDENAME() type=%d offset=%x count=%x %s\n",
+                                               htype,hoffset,hcount,name);
+}
+
+void
+checkRpmIdxREQUIREFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+uint32_t *flagp, flag;
+char   buf[128];
+
+#define mapbit(bit) \
+       if( flag & bit ) { flag&=~bit;strcat(buf,#bit);strcat(buf," "); }
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+flagp=(uint32_t *)(file1->storeaddr+hoffset);
+
+/* This should move to a seperate function for use by multiple tags */
+for(i=0;i<hcount;i++) {
+       buf[0]='\000';
+       flag=htonl(flagp[i]);
+       //fprintf(stderr,"Required Flag: %x ",flag);
+       mapbit(RPMSENSE_RPMLIB);
+       mapbit(RPMSENSE_SCRIPT_POSTUN);
+       mapbit(RPMSENSE_SCRIPT_PREUN);
+       mapbit(RPMSENSE_SCRIPT_POST);
+       mapbit(RPMSENSE_SCRIPT_PRE);
+       mapbit(RPMSENSE_INTERP);
+       mapbit(RPMSENSE_PREREQ);
+       mapbit(RPMSENSE_EQUAL);
+       mapbit(RPMSENSE_GREATER);
+       mapbit(RPMSENSE_LESS);
+       fprintf(stderr,"%s ",buf);
+       if( flag )
+               fprintf(stderr," %x",flag);
+       fprintf(stderr,"\n");
+       }
+}
+
+void
+checkRpmIdxREQUIRENAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    i, hoffset, hcount;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=file1->storeaddr+hoffset;
+for(i=0;i<hcount;i++) {
+       if( strcmp(name,"lsb") == 0 ) 
+               lsbdepidx=i;
+       if( strcmp(name,"rpmlib(PayloadFilesHavePrefix)") == 0 ) 
+               hasPayloadFilesHavePrefix=1;
+       fprintf(stderr,"Required Name: %s\n", name );
+       name+=strlen(name)+1;
+       }
+
+if( lsbdepidx < 0 ) 
+               fprintf(stderr,"RPMTAG_REQUIRENAME did not contain \"lsb\"\n");
+}
+
+void
+checkRpmIdxRPMVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"RPM version: %s\n",name);
+}
+
+void
+checkRpmIdxCHANGELOGTIME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hcount, hoffset, i;
+uint32_t *timep;
+time_t chtime;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+timep=(uint32_t *)(file1->storeaddr+hoffset);
+
+for(i=0;i<hcount;i++) {
+       chtime=htonl(timep[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Changelog time: %s",ctime(&chtime));
+       }
+}
+
+void
+checkRpmIdxCHANGELOGNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=(char *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Changelog name: %s\n",name);
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxCHANGELOGTEXT(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *text;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+text=(char *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Changelog text: %s\n",text);
+       text+=strlen(text)+1;
+       }
+}
+
+void
+checkRpmIdxPREINPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+unsigned char  *name;
+
+hoffset=ntohl(hidx->offset);
+name=(char *)(file1->storeaddr+hoffset);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Pre-install program: %s\n",name);
+fprintf(stderr,"Pre-install program not checked: %s\n",name);
+}
+
+void
+checkRpmIdxPOSTINPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+unsigned char  *name;
+
+hoffset=ntohl(hidx->offset);
+name=(char *)(file1->storeaddr+hoffset);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Post-install program: %s\n",name);
+fprintf(stderr,"Post-install program not checked: %s\n",name);
+}
+
+void
+checkRpmIdxPREUNPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+unsigned char  *name;
+
+hoffset=ntohl(hidx->offset);
+name=(char *)(file1->storeaddr+hoffset);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Pre-uninstall program: %s\n",name);
+fprintf(stderr,"Pre-uninstall program not checked: %s\n",name);
+}
+
+void
+checkRpmIdxPOSTUNPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+unsigned char  *name;
+
+hoffset=ntohl(hidx->offset);
+name=(char *)(file1->storeaddr+hoffset);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Post-uninstall program: %s\n",name);
+fprintf(stderr,"Post-uninstall program not checked: %s\n",name);
+}
+
+void
+checkRpmIdxCOOKIE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+unsigned char  *name;
+
+hoffset=ntohl(hidx->offset);
+name=(char *)(file1->storeaddr+hoffset);
+
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Cookie: %s\n",name);
+}
+
+void
+checkRpmIdxFILEDEVICES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount,i;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filedevs=(uint32_t *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       filedevs[i]=htonl(filedevs[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Filedevs: %x\n",filedevs[i]);
+       }
+}
+
+void
+checkRpmIdxFILEINODES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount,i;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+fileinodes=(uint32_t *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       fileinodes[i]=htonl(fileinodes[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File inode: %d\n",fileinodes[i]);
+       }
+}
+
+void
+checkRpmIdxFILELANGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+filelangs=(char *)(file1->storeaddr+hoffset);
+name=filelangs;
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"File langs: %s\n",name);
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxPROVIDEFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+uint32_t       *flagp,flag;
+
+hoffset=ntohl(hidx->offset);
+flagp=(uint32_t *)(file1->storeaddr+hoffset);
+flag=htonl(*flagp);
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Provide Flag: %x\n",flag);
+fprintf(stderr,"Provide Flag not checked: %x\n",flag);
+}
+
+void
+checkRpmIdxPROVIDEVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    i, hoffset, hcount;
+char   *name;
+
+/*
+ * A STRING_ARRAY because it could be providing multiple things.
+ */
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=file1->storeaddr+hoffset;
+for(i=0;i<hcount;i++) {
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Provide Version: %s\n", name );
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxDIRINDEXES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset, hcount, i;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+dirindicies=(int *)(file1->storeaddr+hoffset);
+for(i=0;i<hcount;i++) {
+       dirindicies[i]=htonl(dirindicies[i]);
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Directory Index: %x\n",dirindicies[i]);
+       }
+}
+
+void
+checkRpmIdxBASENAMES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    i, hoffset, hcount;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+basenames=(char **)malloc(hcount*sizeof(char *));
+name=file1->storeaddr+hoffset;
+for(i=0;i<hcount;i++) {
+       basenames[i]=name;
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Basename: %s\n", name );
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxDIRNAMES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    i, hoffset, hcount;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+numdirnames=hcount;
+dirnames=(char **)malloc(hcount*sizeof(char *));
+name=file1->storeaddr+hoffset;
+for(i=0;i<hcount;i++) {
+       dirnames[i]=name;
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Dirname: %s\n", name );
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxOPTFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Optflags: %s\n", name );
+fprintf(stderr,"Optflags not checked: %s\n", name );
+}
+
+void
+checkRpmIdxPAYLOADFORMAT(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    htag, htype, hoffset, hcount;
+char   *name;
+
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=file1->storeaddr+hoffset;
+if( strcmp(name,"cpio") != 0 ) {
+               fprintf(stderr,"Invalid RPMTAG_PAYLOADFORMAT: expecting \"cpio\"");
+               fprintf(stderr," but found %s\n", name );
+               }
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Payload format: %s\n",name);
+}
+
+void
+checkRpmIdxPAYLOADCOMPRESSOR(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    htag, htype, hoffset, hcount;
+char   *name;
+
+htag=ntohl(hidx->tag);
+htype=ntohl(hidx->type);
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=file1->storeaddr+hoffset;
+if( strcmp(name,"gzip") != 0 ) {
+               fprintf(stderr,"Invalid RPMTAG_PAYLOADCOMPRESSOR: expecting \"gzip\"");
+               fprintf(stderr," but found %s\n", name );
+               }
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Payload compressor: %s\n",name);
+}
+
+void
+checkRpmIdxREQUIREVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    i, hoffset, hcount;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+hcount=ntohl(hidx->count);
+name=file1->storeaddr+hoffset;
+for(i=0;i<hcount;i++) {
+       if( i == lsbdepidx && strcmp(name,validdepver) != 0 ) {
+               fprintf(stderr,"Incorrect version on \"lsb\" dependency: ");
+               fprintf(stderr,"expecting %s but found %s\n",validdepver, name);
+               }
+       if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+               fprintf(stderr,"Required Version: %s\n", name );
+       fprintf(stderr,"Required Version not checked: %s\n", name );
+       name+=strlen(name)+1;
+       }
+}
+
+void
+checkRpmIdxPAYLOADFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Payload flags: %s\n", name );
+fprintf(stderr,"Payload flags not checked: %s\n", name );
+}
+
+void
+checkRpmIdxRHNPLATFORM(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"RHN platform: %s\n", name );
+fprintf(stderr,"RHN platform not checked: %s\n", name );
+}
+
+void
+checkRpmIdxPLATFORM(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal)
+{
+int    hoffset;
+char   *name;
+
+hoffset=ntohl(hidx->offset);
+name=file1->storeaddr+hoffset;
+if( rpmchkdebug&DEBUG_TRACE_CONTENTS )
+       fprintf(stderr,"Platform: %s\n", name );
+fprintf(stderr,"Platform not checked: %s\n", name );
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/idxtbl.c b/lsbpkgchk/src/tests/rpmchk/idxtbl.c
new file mode 100644 (file)
index 0000000..3113471
--- /dev/null
@@ -0,0 +1,75 @@
+/* Generated file - Do Not Edit */
+
+#include "rpmchk.h"
+#include "tagfuncs.h"
+
+RpmIdxTagFuncRec SigTags[] = {
+{RPMTAG_HEADERSIGNATURES,      "RPMTAG_HEADERSIGNATURES",      BIN,    16,     checkRpmIdxHEADERSIGNATURES,    Required,       NotSeen},
+{RPMTAG_HEADERIMMUTABLE,       "RPMTAG_HEADERIMMUTABLE",       BIN,    16,     checkRpmIdxHEADERIMMUTABLE,     Required,       NotSeen},
+{RPMTAG_HEADERI18NTABLE,       "RPMTAG_HEADERI18NTABLE",       STRING_ARRAY,   0,      checkRpmIdxHEADERI18NTABLE,     Required,       NotSeen},
+{SIGTAG_SHA1HEADER,    "SIGTAG_SHA1HEADER",    STRING, 1,      checkRpmIdxSHA1HEADER,  Required,       NotSeen},
+{SIGTAG_SIGSIZE,       "SIGTAG_SIGSIZE",       INT32,  1,      checkRpmIdxSIGSIZE,     Required,       NotSeen},
+{SIGTAG_MD5,   "SIGTAG_MD5",   BIN,    16,     checkRpmIdxMD5, Required,       NotSeen},
+       };
+
+
+int numSigIdxTags = sizeof(SigTags)/sizeof(RpmIdxTagFuncRec);
+
+RpmIdxTagFuncRec HdrTags[] = {
+{RPMTAG_HEADERSIGNATURES,      "RPMTAG_HEADERSIGNATURES",      BIN,    16,     checkRpmIdxHEADERSIGNATURES,    Required,       NotSeen},
+{RPMTAG_HEADERIMMUTABLE,       "RPMTAG_HEADERIMMUTABLE",       BIN,    16,     checkRpmIdxHEADERIMMUTABLE,     Required,       NotSeen},
+{RPMTAG_HEADERI18NTABLE,       "RPMTAG_HEADERI18NTABLE",       STRING_ARRAY,   0,      checkRpmIdxHEADERI18NTABLE,     Required,       NotSeen},
+{RPMTAG_NAME,  "RPMTAG_NAME",  STRING, 1,      checkRpmIdxNAME,        Required,       NotSeen},
+{RPMTAG_VERSION,       "RPMTAG_VERSION",       STRING, 1,      checkRpmIdxVERSION,     Required,       NotSeen},
+{RPMTAG_RELEASE,       "RPMTAG_RELEASE",       STRING, 1,      checkRpmIdxRELEASE,     Required,       NotSeen},
+{RPMTAG_SUMMARY,       "RPMTAG_SUMMARY",       I18NSTRING,     0,      checkRpmIdxSUMMARY,     Required,       NotSeen},
+{RPMTAG_DESCRIPTION,   "RPMTAG_DESCRIPTION",   I18NSTRING,     0,      checkRpmIdxDESCRIPTION, Required,       NotSeen},
+{RPMTAG_BUILDTIME,     "RPMTAG_BUILDTIME",     INT32,  1,      checkRpmIdxBUILDTIME,   Optional,       NotSeen},
+{RPMTAG_BUILDHOST,     "RPMTAG_BUILDHOST",     STRING, 1,      checkRpmIdxBUILDHOST,   Optional,       NotSeen},
+{RPMTAG_SIZE,  "RPMTAG_SIZE",  INT32,  1,      checkRpmIdxSIZE,        Required,       NotSeen},
+{RPMTAG_LICENSE,       "RPMTAG_LICENSE",       STRING, 1,      checkRpmIdxLICENSE,     Required,       NotSeen},
+{RPMTAG_GROUP, "RPMTAG_GROUP", I18NSTRING,     1,      checkRpmIdxGROUP,       Required,       NotSeen},
+{RPMTAG_OS,    "RPMTAG_OS",    STRING, 1,      checkRpmIdxOS,  Required,       NotSeen},
+{RPMTAG_ARCH,  "RPMTAG_ARCH",  STRING, 1,      checkRpmIdxARCH,        Required,       NotSeen},
+{RPMTAG_FILESIZES,     "RPMTAG_FILESIZES",     INT32,  0,      checkRpmIdxFILESIZES,   Required,       NotSeen},
+{RPMTAG_FILEMODES,     "RPMTAG_FILEMODES",     INT16,  0,      checkRpmIdxFILEMODES,   Required,       NotSeen},
+{RPMTAG_FILERDEVS,     "RPMTAG_FILERDEVS",     INT16,  0,      checkRpmIdxFILERDEVS,   Required,       NotSeen},
+{RPMTAG_FILEMTIMES,    "RPMTAG_FILEMTIMES",    INT32,  0,      checkRpmIdxFILEMTIMES,  Required,       NotSeen},
+{RPMTAG_FILEMD5S,      "RPMTAG_FILEMD5S",      STRING_ARRAY,   0,      checkRpmIdxFILEMD5S,    Required,       NotSeen},
+{RPMTAG_FILELINKTOS,   "RPMTAG_FILELINKTOS",   STRING_ARRAY,   0,      checkRpmIdxFILELINKTOS, Required,       NotSeen},
+{RPMTAG_FILEFLAGS,     "RPMTAG_FILEFLAGS",     INT32,  0,      checkRpmIdxFILEFLAGS,   Required,       NotSeen},
+{RPMTAG_FILEUSERNAME,  "RPMTAG_FILEUSERNAME",  STRING_ARRAY,   0,      checkRpmIdxFILEUSERNAME,        Required,       NotSeen},
+{RPMTAG_FILEGROUPNAME, "RPMTAG_FILEGROUPNAME", STRING_ARRAY,   0,      checkRpmIdxFILEGROUPNAME,       Required,       NotSeen},
+{RPMTAG_SOURCERPM,     "RPMTAG_SOURCERPM",     STRING, 1,      checkRpmIdxSOURCERPM,   Optional,       NotSeen},
+{RPMTAG_FILEVERIFYFLAGS,       "RPMTAG_FILEVERIFYFLAGS",       INT32,  0,      checkRpmIdxFILEVERIFYFLAGS,     Required,       NotSeen},
+{RPMTAG_ARCHIVESIZE,   "RPMTAG_ARCHIVESIZE",   INT32,  1,      checkRpmIdxARCHIVESIZE, Required,       NotSeen},
+{RPMTAG_PROVIDENAME,   "RPMTAG_PROVIDENAME",   STRING_ARRAY,   1,      checkRpmIdxPROVIDENAME, Required,       NotSeen},
+{RPMTAG_REQUIREFLAGS,  "RPMTAG_REQUIREFLAGS",  INT32,  0,      checkRpmIdxREQUIREFLAGS,        Required,       NotSeen},
+{RPMTAG_REQUIRENAME,   "RPMTAG_REQUIRENAME",   STRING_ARRAY,   0,      checkRpmIdxREQUIRENAME, Required,       NotSeen},
+{RPMTAG_REQUIREVERSION,        "RPMTAG_REQUIREVERSION",        STRING_ARRAY,   0,      checkRpmIdxREQUIREVERSION,      Required,       NotSeen},
+{RPMTAG_RPMVERSION,    "RPMTAG_RPMVERSION",    STRING, 1,      checkRpmIdxRPMVERSION,  Optional,       NotSeen},
+{RPMTAG_CHANGELOGTIME, "RPMTAG_CHANGELOGTIME", INT32,  0,      checkRpmIdxCHANGELOGTIME,       Required,       NotSeen},
+{RPMTAG_CHANGELOGNAME, "RPMTAG_CHANGELOGNAME", STRING_ARRAY,   0,      checkRpmIdxCHANGELOGNAME,       Required,       NotSeen},
+{RPMTAG_CHANGELOGTEXT, "RPMTAG_CHANGELOGTEXT", STRING_ARRAY,   0,      checkRpmIdxCHANGELOGTEXT,       Required,       NotSeen},
+{RPMTAG_PREINPROG,     "RPMTAG_PREINPROG",     STRING, 1,      checkRpmIdxPREINPROG,   Optional,       NotSeen},
+{RPMTAG_POSTINPROG,    "RPMTAG_POSTINPROG",    STRING, 1,      checkRpmIdxPOSTINPROG,  Optional,       NotSeen},
+{RPMTAG_PREUNPROG,     "RPMTAG_PREUNPROG",     STRING, 1,      checkRpmIdxPREUNPROG,   Required,       NotSeen},
+{RPMTAG_POSTUNPROG,    "RPMTAG_POSTUNPROG",    STRING, 1,      checkRpmIdxPOSTUNPROG,  Required,       NotSeen},
+{RPMTAG_COOKIE,        "RPMTAG_COOKIE",        STRING, 1,      checkRpmIdxCOOKIE,      Required,       NotSeen},
+{RPMTAG_FILEDEVICES,   "RPMTAG_FILEDEVICES",   INT32,  0,      checkRpmIdxFILEDEVICES, Required,       NotSeen},
+{RPMTAG_FILEINODES,    "RPMTAG_FILEINODES",    INT32,  0,      checkRpmIdxFILEINODES,  Required,       NotSeen},
+{RPMTAG_FILELANGS,     "RPMTAG_FILELANGS",     STRING_ARRAY,   0,      checkRpmIdxFILELANGS,   Required,       NotSeen},
+{RPMTAG_PROVIDEFLAGS,  "RPMTAG_PROVIDEFLAGS",  INT32,  1,      checkRpmIdxPROVIDEFLAGS,        Required,       NotSeen},
+{RPMTAG_PROVIDEVERSION,        "RPMTAG_PROVIDEVERSION",        STRING_ARRAY,   0,      checkRpmIdxPROVIDEVERSION,      Required,       NotSeen},
+{RPMTAG_DIRINDEXES,    "RPMTAG_DIRINDEXES",    INT32,  0,      checkRpmIdxDIRINDEXES,  Required,       NotSeen},
+{RPMTAG_BASENAMES,     "RPMTAG_BASENAMES",     STRING_ARRAY,   0,      checkRpmIdxBASENAMES,   Required,       NotSeen},
+{RPMTAG_DIRNAMES,      "RPMTAG_DIRNAMES",      STRING_ARRAY,   0,      checkRpmIdxDIRNAMES,    Required,       NotSeen},
+{RPMTAG_OPTFLAGS,      "RPMTAG_OPTFLAGS",      STRING, 1,      checkRpmIdxOPTFLAGS,    Optional,       NotSeen},
+{RPMTAG_PAYLOADFORMAT, "RPMTAG_PAYLOADFORMAT", STRING, 1,      checkRpmIdxPAYLOADFORMAT,       Required,       NotSeen},
+{RPMTAG_PAYLOADCOMPRESSOR,     "RPMTAG_PAYLOADCOMPRESSOR",     STRING, 1,      checkRpmIdxPAYLOADCOMPRESSOR,   Required,       NotSeen},
+{RPMTAG_PAYLOADFLAGS,  "RPMTAG_PAYLOADFLAGS",  STRING, 1,      checkRpmIdxPAYLOADFLAGS,        Required,       NotSeen},
+{RPMTAG_RHNPLATFORM,   "RPMTAG_RHNPLATFORM",   STRING, 1,      checkRpmIdxRHNPLATFORM, Optional,       NotSeen},
+{RPMTAG_PLATFORM,      "RPMTAG_PLATFORM",      STRING, 1,      checkRpmIdxPLATFORM,    Optional,       NotSeen},
+       };
+
+int numHdrIdxTags = sizeof(HdrTags)/sizeof(RpmIdxTagFuncRec);
diff --git a/lsbpkgchk/src/tests/rpmchk/lead.c b/lsbpkgchk/src/tests/rpmchk/lead.c
new file mode 100644 (file)
index 0000000..4a9f1c6
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <string.h>
+#include "rpmchk.h"
+#include "../tetj/tetj.h"
+
+void
+checkRpmLead(RpmFile *file1, struct tetj_handle *journal)
+{
+#define TMP_STRING_SIZE (400)
+char tmp_string[TMP_STRING_SIZE+1];
+RpmLead        *rlead;
+
+rlead=(RpmLead *)file1->addr;
+file1->laddr=rlead;
+
+tetj_tp_count++;
+tetj_purpose_start(journal, tetj_activity_count, tetj_tp_count, "Check magic value");
+if(strncmp(rlead->magic,RPMMAG,SRPMMAG)) {
+        snprintf( tmp_string, TMP_STRING_SIZE, "compareRpmLead: magic isn't expected value RPMMAG, found %x %x %x %x instead\n", rlead->magic[0], rlead->magic[1], rlead->magic[2], rlead->magic[3]); 
+        fprintf(stderr, "%s\n", tmp_string);
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count, 0, 0, 0, tmp_string);
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL);
+} else {
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_PASS); 
+}
+tetj_purpose_end(journal, tetj_activity_count, tetj_tp_count); 
+
+#define checkhdrfield( member, value ) \
+{ \
+tetj_tp_count++; \
+tetj_purpose_start(journal, tetj_activity_count, tetj_tp_count, "Check header field "#member" is "#value); \
+if( rlead->member != value ) { \
+        snprintf( tmp_string, TMP_STRING_SIZE, "compareRpmLead: %s isn't expected value %s, found %x instead\n", #member, #value, rlead->member); \
+        fprintf(stderr, "%s\n", tmp_string); \
+        tetj_testcase_info(journal, tetj_activity_count, tetj_tp_count, 0, 0, 0, tmp_string); \
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_FAIL); \
+        } \
+else \
+{ \
+        tetj_result(journal, tetj_activity_count, tetj_tp_count, TETJ_PASS); \
+} \
+tetj_purpose_end(journal, tetj_activity_count, tetj_tp_count); \
+        }
+
+checkhdrfield( major, RPMFILEVERMAJ )
+checkhdrfield( minor, RPMFILEVERMIN )
+
+checkhdrfield( type, htons(RPMBINPKG) )
+
+checkhdrfield( archnum, htons(RPMARCH) )
+
+checkhdrfield( osnum, htons(RPMOS) )
+
+checkhdrfield( signature_type, htons(RPMSIGTYPE) )
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/makefile b/lsbpkgchk/src/tests/rpmchk/makefile
new file mode 100644 (file)
index 0000000..3281881
--- /dev/null
@@ -0,0 +1,33 @@
+CFLAGS=-g -Wall
+
+OBJS=archive.o hdr.o idxtag.o lead.o rpmchk.o util.o vals.o fhs.o idxtbl.o \
+       md5c.o
+GENSRCS=rpmtag.h idxtbl.c
+LIBS= ../tetj/libtetj.a
+LIB=librpmchk.a
+
+all: $(LIB) test
+
+install:
+
+$(OBJS): $(GENSRCS)
+
+$(LIB): $(OBJS)
+       rm -f $(LIB);ar clq $(LIB) $(OBJS)
+
+test: test.c $(LIB) $(LIBS)
+       cc -o test $(CFLAGS) test.c $(LIB) $(LIBS) -lz
+
+idx.o: rpmtag.h
+
+rpmtag.h:
+       ./mktaghdr >rpmtag.h
+
+idxtbl.c:
+       ./mktagtbl >idxtbl.c
+
+clean:
+       rm -f $(OBJS) $(LIB)
+
+distclean: clean
+       rm -f $(GENSRCS)
diff --git a/lsbpkgchk/src/tests/rpmchk/md5.h b/lsbpkgchk/src/tests/rpmchk/md5.h
new file mode 100644 (file)
index 0000000..d07667e
--- /dev/null
@@ -0,0 +1,54 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.  
+                                                                    
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.  
+                                                                    
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.  
+ */
+
+#ifndef _MD5_H_
+#define _MD5_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*#include "global.h"  */
+typedef unsigned int UINT4;
+typedef unsigned char *POINTER;
+#define PROTO_LIST(list) ()
+
+/* MD5 context. */
+typedef struct {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+  ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lsbpkgchk/src/tests/rpmchk/md5c.c b/lsbpkgchk/src/tests/rpmchk/md5c.c
new file mode 100644 (file)
index 0000000..378360f
--- /dev/null
@@ -0,0 +1,349 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.  
+                                                                    
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.  
+                                                                    
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.  
+ */
+
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+  ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+  ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+   Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+    (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+    (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+    (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+    (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void
+MD5Init(
+       MD5_CTX *context                             /* context */
+       )
+{
+  context->count[0] = context->count[1] = 0;
+
+  /* Load magic initialization constants.
+   */
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+     operation, processing another message block, and updating the
+     context.
+ */
+void
+MD5Update (
+       MD5_CTX *context,                               /* context */
+       unsigned char *input,                       /* input block */
+       unsigned int inputLen             /* length of input block */
+       )
+{
+  unsigned int i, index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+      < ((UINT4)inputLen << 3))
+    context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+  
+  partLen = 64 - index;
+  
+  /* Transform as many times as possible.
+   */
+  if (inputLen >= partLen) {
+    MD5_memcpy
+      ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+    MD5Transform (context->state, context->buffer);
+  
+    for (i = partLen; i + 63 < inputLen; i += 64)
+      MD5Transform (context->state, &input[i]);
+    
+    index = 0;
+  }
+  else
+    i = 0;
+  
+  /* Buffer remaining input */
+  MD5_memcpy 
+    ((POINTER)&context->buffer[index], (POINTER)&input[i],
+     inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+     the message digest and zeroizing the context.
+ */
+void
+MD5Final (
+       unsigned char digest[16],                /* message digest */
+       MD5_CTX *context                                /* context */
+       )
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+   */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  MD5Update (context, PADDING, padLen);
+  
+  /* Append length (before padding) */
+  MD5Update (context, bits, 8);
+
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+  
+  /* Zeroize sensitive information.
+   */
+  MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void
+MD5Transform (
+       UINT4 state[4],
+       unsigned char block[64]
+       )
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+  
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+  /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+  
+  /* Zeroize sensitive information.
+   */
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+     a multiple of 4.
+ */
+static void
+Encode (
+       unsigned char *output,
+       UINT4 *input,
+       unsigned int len
+       )
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+    output[j] = (unsigned char)(input[i] & 0xff);
+    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+     a multiple of 4.
+ */
+static void
+Decode (
+       UINT4 *output,
+       unsigned char *input,
+       unsigned int len
+       )
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+static void
+MD5_memcpy (
+       POINTER output,
+       POINTER input,
+       unsigned int len 
+       )
+{
+  unsigned int i;
+  
+  for (i = 0; i < len; i++)
+    output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void
+MD5_memset (
+       POINTER output,
+       int value,
+       unsigned int len
+       )
+{
+  unsigned int i;
+  
+  for (i = 0; i < len; i++)
+    ((char *)output)[i] = (char)value;
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/mktaghdr b/lsbpkgchk/src/tests/rpmchk/mktaghdr
new file mode 100755 (executable)
index 0000000..4dc4830
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+
+use Mysql;
+
+use Env qw(LSBUSER LSBDBPASSWD LSBDB LSBDBHOST);
+
+$Dbh = Mysql->connect($LSBDBHOST,$LSBDB,$LSBUSER, $LSBDBPASSWD) || die $Mysql::db_errstr;
+
+sub
+dumpenum($$)
+{
+local($ttype,$tname)=@_;
+
+$select = "SELECT DISTINCT * FROM RpmTag ";
+$select.= "WHERE Rgroup='".$ttype."' ";
+$select.= "ORDER BY Rtag ";
+
+#print "$select\n";
+
+$sth = $Dbh->query($select) || die $Dbh->errmsg();
+
+print "typedef enum {\n";
+
+for(1..$sth->numrows) {
+       %entry=$sth->fetchhash;
+       printf "\t%s\t= %d,\n", $entry{'Rname'}, $entry{'Rtag'};
+       }
+printf "\t} %s;\n\n", $tname;
+}
+
+print "/* Generated file - Do Not Edit */\n\n";
+
+dumpenum("Private","HdrPrivIndexTag");
+dumpenum("Signature","SigIndexTag");
+dumpenum("Header","RpmIndexTag");
+
diff --git a/lsbpkgchk/src/tests/rpmchk/mktagtbl b/lsbpkgchk/src/tests/rpmchk/mktagtbl
new file mode 100755 (executable)
index 0000000..946d69b
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use Mysql;
+
+use Env qw(LSBUSER LSBDBPASSWD LSBDB LSBDBHOST);
+
+$Dbh = Mysql->connect($LSBDBHOST,$LSBDB,$LSBUSER, $LSBDBPASSWD) || die $Mysql::db_errstr;
+
+sub
+dumptable($$)
+{
+local($ttype,$tname)=@_;
+
+$select = "SELECT DISTINCT * FROM RpmTag ";
+$select.= "WHERE Rgroup='Private' OR Rgroup='".$ttype."' ";
+$select.= "ORDER BY Rgroup,Rtag ";
+
+#print "$select\n";
+
+$sth = $Dbh->query($select) || die $Dbh->errmsg();
+
+printf "RpmIdxTagFuncRec %s[] = {\n", $tname;
+
+for(1..$sth->numrows) {
+       %entry=$sth->fetchhash;
+       printf "{%s,\t", $entry{'Rname'};
+       printf "\"%s\",\t", $entry{'Rname'};
+       printf "%s,\t", $entry{'Rtype'};
+       printf "%s,\t", $entry{'Rcount'};
+       split('_',$entry{'Rname'});
+       $tagname=@_[1];
+       printf "checkRpmIdx%s,\t", $tagname;
+       printf "%s,\t", $entry{'Rstatus'};
+       printf "NotSeen},\n";
+       }
+printf "\t};\n\n", $tname;
+}
+
+print "/* Generated file - Do Not Edit */\n\n";
+print "#include \"rpmchk.h\"\n";
+print "#include \"tagfuncs.h\"\n\n";
+
+dumptable("Signature","SigTags");
+print "\nint numSigIdxTags = sizeof(SigTags)/sizeof(RpmIdxTagFuncRec);\n\n";
+dumptable("Header","HdrTags");
+print "int numHdrIdxTags = sizeof(HdrTags)/sizeof(RpmIdxTagFuncRec);\n";
+
diff --git a/lsbpkgchk/src/tests/rpmchk/rpmchk.c b/lsbpkgchk/src/tests/rpmchk/rpmchk.c
new file mode 100644 (file)
index 0000000..a18aba2
--- /dev/null
@@ -0,0 +1,16 @@
+#include "rpmchk.h"
+
+void
+checkRpm(RpmFile *file1, struct tetj_handle *journal)
+{
+
+checkRpmLead(file1, journal);
+
+file1->signature=(RpmHeader *)(file1->addr+sizeof(RpmLead));
+file1->nexthdr=file1->signature;
+
+/* RPM packages should have 2 Headers, the Signature, and the Header */
+checkRpmSignature(file1, journal);
+checkRpmHeader(file1, journal);
+checkRpmArchive(file1, journal);
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/rpmchk.h b/lsbpkgchk/src/tests/rpmchk/rpmchk.h
new file mode 100644 (file)
index 0000000..043b928
--- /dev/null
@@ -0,0 +1,213 @@
+#ifndef _RPMCHK_H
+#define _RPMCHK_H
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+struct tetj_handle;
+
+/*
+ * RPM file Lead
+ */
+typedef struct rpmlead {
+    unsigned char magic[4];
+    unsigned char major, minor;
+    uint16_t type;
+    uint16_t archnum;
+    char name[66];
+    uint16_t osnum;
+    uint16_t signature_type;
+    char reserved[16];
+    } RpmLead;
+
+#define RPMMAG "\355\253\356\333"
+#define SRPMMAG        4
+
+#define RPMFILEVERMAJ  0x03
+#define RPMFILEVERMIN  0x00
+
+#define RPMBINPKG      0x0000
+#define RPMSRCPKG      0x0001
+
+#if defined(__i386__)
+#define RPMARCH        0x0001
+#endif
+#if defined(__ia64__)
+#define RPMARCH        0x0009
+#endif
+
+#define RPMOS  0x0001 /* Linux */
+
+#define RPMSIGTYPE     0x0005
+
+typedef struct rpmheader {
+    unsigned char magic[3];
+    unsigned char version;
+    char reserved[4];
+    uint32_t   nindex;
+    uint32_t   hsize;
+    } RpmHeader;
+
+#define RPMHDRMAG "\216\255\350"
+#define SRPMHDRMAG     3
+
+#define RPMHDRVER      1
+
+/*
+ * Each Index has a type associated with it. These are the types which
+ * may be used.
+ */
+typedef enum {
+       NULL_TYPE=0,
+       CHAR=1,
+       INT8=2,
+       INT16=3,
+       INT32=4,
+       INT64=5,
+       STRING=6,
+       BIN=7,
+       STRING_ARRAY=8,
+       I18NSTRING=9
+       } RpmIndexType;
+
+#include "rpmtag.h"
+
+typedef struct rpmhdrindex {
+    uint32_t   tag;
+    uint32_t   type;
+    uint32_t   offset;
+    uint32_t   count;
+    } RpmHdrIndex;
+
+/*
+ * Require Flags.
+ */
+typedef enum {
+       RPMSENSE_LESS   = (1 << 1),
+       RPMSENSE_GREATER= (1 << 2),
+       RPMSENSE_EQUAL  = (1 << 3),
+       RPMSENSE_PREREQ = (1 << 6),
+       RPMSENSE_INTERP = (1 << 8),
+       RPMSENSE_SCRIPT_PRE = (1 << 9),
+       RPMSENSE_SCRIPT_POST = (1 << 10),
+       RPMSENSE_SCRIPT_PREUN = (1 << 11),
+       RPMSENSE_SCRIPT_POSTUN = (1 << 12),
+       RPMSENSE_RPMLIB = (1 << 24), /* rpmlib(feature) dependency. */
+       } rpmRequireFlags;
+/*
+ * An in memory representation of the RPM file.
+ */
+typedef        struct  {
+       int     fd;
+       caddr_t     addr;  /* Start address of the file */
+       int     size;
+       RpmLead *laddr;
+       RpmHeader       *signature;
+       RpmHeader       *header;
+       RpmHeader       *nexthdr;
+       caddr_t     storeaddr;  /* Start store for the current header */
+       caddr_t     archive;
+       }       RpmFile;
+
+/* RPM Index things */
+
+typedef void (*IdxTagFunc)(RpmFile *, RpmHdrIndex *, struct tetj_handle *);
+
+typedef enum { Required, Optional } RpmIdxReqd ;
+
+typedef enum { NotSeen, Seen } RpmIdxStatus ;
+
+typedef struct {
+       RpmIndexTag     tag;
+       char            *name;
+       RpmIndexType    type;
+       int             count;
+       IdxTagFunc      func;
+       RpmIdxReqd      reqd;
+       RpmIdxStatus    status;
+       } RpmIdxTagFuncRec;
+
+extern RpmIdxTagFuncRec SigTags[];
+extern int numSigIdxTags;
+extern RpmIdxTagFuncRec HdrTags[];
+extern int numHdrIdxTags;
+
+/*
+ * Archive format -
+ * really cpio, but it doesn't actually match the cpio definition ?!?!?!
+ */
+
+typedef struct {
+       char    c_magic[6];
+       char    c_ino[8];
+       char    c_mode[8];
+       char    c_uid[8];
+       char    c_gid[8];
+       char    c_nlink[8];
+       char    c_mtime[8];
+       char    c_filesize[8];
+       char    c_devmajor[8];
+       char    c_devminor[8];
+       char    c_rdevmajor[8];
+       char    c_rdevminor[8];
+       char    c_namesize[8];
+       char    c_checksum[8];
+       } RpmArchiveHeader;
+
+/*
+ * Debugging interface: Set the environment variable RPMCHK_DEBUG to a value
+ * that corresponds to the bits defined below.
+ */
+#define DEBUG_ENV_OVERRIDES    0x0001
+#define DEBUG_TRACE_TAGS       0x0002
+#define DEBUG_TRACE_CONTENTS   0x0004
+
+extern int rpmchkdebug;
+
+/* vals.c */
+extern char *architecture;
+extern char *validos;
+extern char *validdepver;
+extern char *pkgname;
+extern unsigned char *sigdata;
+extern int lsbdepidx;
+extern uint32_t sigsize;
+extern uint32_t archivesize;
+extern uint32_t rpmtagsize;
+extern uint32_t *filesizes;
+extern uint16_t *filemodes;
+extern uint32_t *filedevs;
+extern uint16_t *filerdevs;
+extern uint32_t *fileinodes;
+extern uint32_t *filetimes;
+extern char *filemd5s;
+extern char *filelinktos;
+extern char *fileusernames;
+extern char *filegroupnames;
+extern char *filelangs;
+extern uint32_t  *dirindicies;
+extern char **basenames;
+extern char **dirnames;
+extern int  numdirnames;
+extern int  hasPayloadFilesHavePrefix;
+
+/* util.c */
+extern RpmFile *OpenRpmFile(char *name);
+extern void checkRpm(RpmFile *file1, struct tetj_handle *journal);
+extern void checkRpmLead(RpmFile *file1, struct tetj_handle *journal);
+extern void checkRpmHeader(RpmFile *file1, struct tetj_handle *journal);
+
+/* fhs.c */
+extern void checkRpmArchiveFilename(char *filename, struct tetj_handle *journal);
+
+/* archive.c */
+void checkRpmArchive(RpmFile *file1, struct tetj_handle *journal);
+
+/* hdr.c */
+void checkRpmHdr(RpmFile *file1, struct tetj_handle *journal);
+void checkRpmSignature(RpmFile *file1, struct tetj_handle *journal);
+void checkRpmHeader(RpmFile *file1, struct tetj_handle *journal);
+
+
+#endif /* _RPMCHK_H */
diff --git a/lsbpkgchk/src/tests/rpmchk/rpmtag.h b/lsbpkgchk/src/tests/rpmchk/rpmtag.h
new file mode 100644 (file)
index 0000000..a5d92c1
--- /dev/null
@@ -0,0 +1,68 @@
+/* Generated file - Do Not Edit */
+
+typedef enum {
+       RPMTAG_HEADERSIGNATURES = 62,
+       RPMTAG_HEADERIMMUTABLE  = 63,
+       RPMTAG_HEADERI18NTABLE  = 100,
+       } HdrPrivIndexTag;
+
+typedef enum {
+       SIGTAG_SHA1HEADER       = 265,
+       SIGTAG_SIGSIZE  = 1000,
+       SIGTAG_MD5      = 1004,
+       } SigIndexTag;
+
+typedef enum {
+       RPMTAG_NAME     = 1000,
+       RPMTAG_VERSION  = 1001,
+       RPMTAG_RELEASE  = 1002,
+       RPMTAG_SUMMARY  = 1004,
+       RPMTAG_DESCRIPTION      = 1005,
+       RPMTAG_BUILDTIME        = 1006,
+       RPMTAG_BUILDHOST        = 1007,
+       RPMTAG_SIZE     = 1009,
+       RPMTAG_LICENSE  = 1014,
+       RPMTAG_GROUP    = 1016,
+       RPMTAG_OS       = 1021,
+       RPMTAG_ARCH     = 1022,
+       RPMTAG_FILESIZES        = 1028,
+       RPMTAG_FILEMODES        = 1030,
+       RPMTAG_FILERDEVS        = 1033,
+       RPMTAG_FILEMTIMES       = 1034,
+       RPMTAG_FILEMD5S = 1035,
+       RPMTAG_FILELINKTOS      = 1036,
+       RPMTAG_FILEFLAGS        = 1037,
+       RPMTAG_FILEUSERNAME     = 1039,
+       RPMTAG_FILEGROUPNAME    = 1040,
+       RPMTAG_SOURCERPM        = 1044,
+       RPMTAG_FILEVERIFYFLAGS  = 1045,
+       RPMTAG_ARCHIVESIZE      = 1046,
+       RPMTAG_PROVIDENAME      = 1047,
+       RPMTAG_REQUIREFLAGS     = 1048,
+       RPMTAG_REQUIRENAME      = 1049,
+       RPMTAG_REQUIREVERSION   = 1050,
+       RPMTAG_RPMVERSION       = 1064,
+       RPMTAG_CHANGELOGTIME    = 1080,
+       RPMTAG_CHANGELOGNAME    = 1081,
+       RPMTAG_CHANGELOGTEXT    = 1082,
+       RPMTAG_PREINPROG        = 1085,
+       RPMTAG_POSTINPROG       = 1086,
+       RPMTAG_PREUNPROG        = 1087,
+       RPMTAG_POSTUNPROG       = 1088,
+       RPMTAG_COOKIE   = 1094,
+       RPMTAG_FILEDEVICES      = 1095,
+       RPMTAG_FILEINODES       = 1096,
+       RPMTAG_FILELANGS        = 1097,
+       RPMTAG_PROVIDEFLAGS     = 1112,
+       RPMTAG_PROVIDEVERSION   = 1113,
+       RPMTAG_DIRINDEXES       = 1116,
+       RPMTAG_BASENAMES        = 1117,
+       RPMTAG_DIRNAMES = 1118,
+       RPMTAG_OPTFLAGS = 1122,
+       RPMTAG_PAYLOADFORMAT    = 1124,
+       RPMTAG_PAYLOADCOMPRESSOR        = 1125,
+       RPMTAG_PAYLOADFLAGS     = 1126,
+       RPMTAG_RHNPLATFORM      = 1131,
+       RPMTAG_PLATFORM = 1132,
+       } RpmIndexTag;
+
diff --git a/lsbpkgchk/src/tests/rpmchk/tagfuncs.h b/lsbpkgchk/src/tests/rpmchk/tagfuncs.h
new file mode 100644 (file)
index 0000000..9fa91d2
--- /dev/null
@@ -0,0 +1,61 @@
+/* idxtag.c */
+void checkRpmIdx(RpmFile *file1, RpmHdrIndex *hidx, RpmIdxTagFuncRec Tags[], int numtags, struct tetj_handle *journal);
+void checkRpmIdxHEADERSIGNATURES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxHEADERIMMUTABLE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxHDRREGIONS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxHEADERI18NTABLE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxHEADERSIGBASE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxSIGSIZE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxMD5(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxSHA1HEADER(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxRELEASE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxSUMMARY(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxDESCRIPTION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxBUILDTIME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxBUILDHOST(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxSIZE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxLICENSE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxGROUP(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxOS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxARCH(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILESIZES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEMODES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILERDEVS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEMTIMES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEMD5S(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILELINKTOS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEUSERNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEGROUPNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxSOURCERPM(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEVERIFYFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxARCHIVESIZE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPROVIDENAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxREQUIREFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxREQUIRENAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxRPMVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxCHANGELOGTIME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxCHANGELOGNAME(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxCHANGELOGTEXT(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPREINPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPOSTINPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPREUNPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPOSTUNPROG(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxCOOKIE(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEDEVICES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILEINODES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxFILELANGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPROVIDEFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPROVIDEVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxDIRINDEXES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxBASENAMES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxDIRNAMES(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxOPTFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPAYLOADFORMAT(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPAYLOADCOMPRESSOR(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxREQUIREVERSION(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPAYLOADFLAGS(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxRHNPLATFORM(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
+void checkRpmIdxPLATFORM(RpmFile *file1, RpmHdrIndex *hidx, struct tetj_handle *journal);
diff --git a/lsbpkgchk/src/tests/rpmchk/test.c b/lsbpkgchk/src/tests/rpmchk/test.c
new file mode 100644 (file)
index 0000000..db5aa77
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "rpmchk.h"
+
+void usage(char *progname)
+{
+fprintf(stderr,"Usage: %s rpmname\n",progname);
+exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+RpmFile        *rpmfile;
+char   *ptr;
+
+if( argc != 2 ) {
+       fprintf(stderr, "%s: bad argument count %d\n", argv[0], argc );
+       usage(argv[0]);
+       }
+
+if( (rpmfile = OpenRpmFile(argv[1])) == NULL ) {
+       fprintf(stderr, "%s: Unable to open file %s\n", argv[0], argv[1] );
+       usage(argv[0]);
+       }
+
+if( (ptr=getenv("RPMCHK_DEBUG")) != NULL ) {
+        rpmchkdebug=strtod(ptr,NULL);
+        if( rpmchkdebug&DEBUG_ENV_OVERRIDES )
+                fprintf(stderr,"rpmchk debug set to 0x%x\n", rpmchkdebug );
+        }
+
+checkRpm(rpmfile, NULL);
+
+exit(0);
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/util.c b/lsbpkgchk/src/tests/rpmchk/util.c
new file mode 100644 (file)
index 0000000..d27b9c9
--- /dev/null
@@ -0,0 +1,63 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include "rpmchk.h"
+
+RpmFile        *OpenRpmFile( char *name )
+{
+RpmFile        *efile;
+struct stat    stat;
+
+if( (efile=(RpmFile *)calloc(1,sizeof(RpmFile))) == NULL ) {
+       fprintf(stderr, "Unable to alloc efile memory for %s\n", name );
+       return NULL;
+       }
+
+if( (efile->fd=open(name, O_RDONLY, 0666)) < 0 ) {
+       perror( "unable to open() file" );
+       free(efile);
+       return NULL;
+       }
+
+if( fstat(efile->fd, &stat ) < 0 ) {
+       perror( "unable to stat() file" );
+       close(efile->fd);
+       free(efile);
+       return NULL;
+       }
+
+efile->size=stat.st_size;
+
+if( efile->size == 0 ) {
+       fprintf( stderr, "Zero length file\n" );
+       close(efile->fd);
+       free(efile);
+       exit(-1);       /* Silently exit */
+       }
+
+if( (efile->addr=mmap(0, efile->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, efile->fd, 0)) == (caddr_t)-1 ) {
+       perror( "unable to mmap() file" );
+       close(efile->fd);
+       free(efile);
+       return NULL;
+       }
+
+/*
+fprintf(stderr,"%d bytes at %x", efile->size, efile->addr );
+fprintf(stderr,"to %x\n", efile->addr+efile->size );
+*/
+
+if( memcmp(efile->addr, RPMMAG, SRPMMAG) ) {
+       fprintf( stderr, "file not RPM\n" );
+       close(efile->fd);
+       free(efile);
+       exit(-1);       /* Silently exit */
+       }
+
+return efile;
+}
diff --git a/lsbpkgchk/src/tests/rpmchk/vals.c b/lsbpkgchk/src/tests/rpmchk/vals.c
new file mode 100644 (file)
index 0000000..d536d96
--- /dev/null
@@ -0,0 +1,47 @@
+#include "rpmchk.h"
+/*
+ * This file contains some values which must match, and some places to
+ * stick things which are discovered in one place, but used in another.
+ */
+char *architecture =
+#if defined(__i386__)
+       "i486";
+#elif defined(__ia64__)
+       "ia64";
+#elif defined(__powerpc__)
+       "powerpc";
+#else
+       "unknown architecture";
+#endif
+
+char *validos = "linux";
+char *validdepver = "1.2";
+
+char *pkgname;
+int  lsbdepidx=-1;
+
+/* Stuff that we read in one part, but need to use for validation in
+ * another part. 
+ */
+unsigned char *sigdata;
+uint32_t  sigsize;
+uint32_t  archivesize;
+uint32_t  rpmtagsize;
+uint32_t *filesizes;
+uint16_t *filemodes;
+uint32_t *filedevs;
+uint16_t *filerdevs;
+uint32_t *fileinodes;
+uint32_t *filetimes;
+char   *filemd5s;
+char   *filelinktos;
+char   *fileusernames;
+char   *filegroupnames;
+char   *filelangs;
+uint32_t       *dirindicies;
+char   **basenames;
+char   **dirnames;
+int    numdirnames;
+
+int    hasPayloadFilesHavePrefix;
+int    rpmchkdebug;
diff --git a/lsbpkgchk/src/tests/tetj/Makefile b/lsbpkgchk/src/tests/tetj/Makefile
new file mode 100644 (file)
index 0000000..12c8b76
--- /dev/null
@@ -0,0 +1,14 @@
+CFLAGS=-g -Wall
+OBJS=tetj.o
+
+LIB=libtetj.a
+
+all: $(LIB) 
+
+install:
+
+$(LIB): $(OBJS)
+       rm -f $(LIB);ar clq $(LIB) $(OBJS)
+
+clean:
+       rm -f $(OBJS) $(LIB)
diff --git a/lsbpkgchk/src/tests/tetj/tetj.c b/lsbpkgchk/src/tests/tetj/tetj.c
new file mode 100644 (file)
index 0000000..29b6d9c
--- /dev/null
@@ -0,0 +1,224 @@
+/* Interface for generating TET like report journals
+ *
+ * This intended to be a simple way of creating journals which
+ * can be analysed using standard TET journal tools without
+ * having to compile or link against the TET libraries.
+ * 
+ * (C) Copyright 2002 The Free Standards Group Inc
+ *
+ * 2002/03/19 Chris Yeoh, IBM
+ *
+ * This is Revision: 1.3 
+ * 
+ * Log: tetj.c,v 
+ * Revision 1.3  2002/04/29 04:39:06  cyeoh
+ * Adds support for 'IC Start' and 'IC End' markers in
+ * the journal file
+ *
+ * Revision 1.2  2002/04/29 04:12:05  cyeoh
+ * Adds tetj_purpose_end
+ * Adds IC Start markers
+ *
+ * Revision 1.1  2002/03/19 06:07:49  cyeoh
+ * Adds simple interface for generating TET journals
+ *
+ *
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <errno.h>
+
+#include "tetj.h"
+
+struct tetj_handle
+{
+  FILE *journal;
+};
+
+int tetj_activity_count = 0;
+int tetj_tp_count = 0;
+
+static char *get_current_time_string()
+{
+  static char time_string[20];
+  time_t current_time;
+
+  current_time = time(NULL);
+  strftime(time_string, 20, "%H:%M:%S", localtime(&current_time));
+  return time_string;
+}
+
+static char *get_result_string(enum testcase_results result)
+{
+  switch (result)
+  {
+  case TETJ_PASS: 
+    return "PASS";
+  case TETJ_FAIL:
+    return "FAIL";
+  case TETJ_UNRESOLVED:
+    return "UNRESOLVED";
+  case TETJ_NOTINUSE:
+    return "NOTINUSE";
+  case TETJ_UNSUPPORTED:
+    return "UNSUPPORTED";
+  case TETJ_UNTESTED:
+    return "UNTESTED";
+  case TETJ_UNINITIATED:
+    return "UNITIATED";
+  case TETJ_UNREPORTED:
+    return "UNREPORTED";
+  case TETJ_WARNING:
+    return "WARNING";
+  case TETJ_FIP:
+    return "FIP";
+  case TETJ_NOTIMP:
+    return "NOTIMP";
+  case TETJ_UNAPPROVE:
+    return "UNAPPROVE";
+  default:
+    return "UNKNOWN";
+  }
+}
+
+int tetj_start_journal(const char *pathname, struct tetj_handle **handle,
+                       char *command_run)
+{
+  struct utsname uname_info;
+  char datetime[20];
+  time_t current_time;
+  uid_t uid;
+  struct passwd *pwent;
+
+  *handle = malloc(sizeof(struct tetj_handle));
+
+  if ( ((*handle)->journal = fopen(pathname, "w")) == NULL )
+  {
+    return errno;
+  }
+  
+  if (uname(&uname_info)!=0)
+  {
+    return errno;
+  }    
+
+  current_time = time(NULL);
+  strftime(datetime, 20, "%H:%M:%S %Y%m%d", localtime(&current_time));
+  uid = getuid();
+  pwent = getpwuid(uid);
+  
+  fprintf((*handle)->journal, 
+          "0|lsb-0.1 %s|User: %s (%i) TCC Start, Command line: %s\n",
+          datetime, pwent ? pwent->pw_name : "", uid, command_run);
+
+  fprintf((*handle)->journal, "5|%s %s %s %s %s|System Information\n",
+          uname_info.sysname, uname_info.nodename, uname_info.release,
+          uname_info.version, uname_info.machine);
+          
+  return 0;
+}
+
+int tetj_close_journal(struct tetj_handle *handle)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "900|%s|TCC End\n", get_current_time_string());
+    return fclose(handle->journal);
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+void tetj_add_config(struct tetj_handle *handle, char *message)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "30||%s\n", message);
+  }
+}
+
+void tetj_add_controller_error(struct tetj_handle *handle, char *message)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "50||%s\n", message);
+  }
+}
+
+void tetj_testcase_start(struct tetj_handle *handle, 
+                         unsigned int activity, char *testcase, 
+                         char *message)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "10|%u %s %s|%s\n",
+            activity, testcase, get_current_time_string(), message);
+  }
+}
+
+void tetj_testcase_end(struct tetj_handle *handle, 
+                       unsigned int activity, char *testcase, 
+                       char *message)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "80|%u %s %s|%s\n",
+            activity, testcase, get_current_time_string(), message);
+  }
+}
+
+void tetj_purpose_start(struct tetj_handle *handle,
+                        unsigned int activity, unsigned int tpnumber, 
+                        char *message)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "400|%u %u %s|IC Start\n",
+            activity, tpnumber, get_current_time_string());
+    fprintf(handle->journal, "200|%u %u %s|%s\n",
+            activity, tpnumber, get_current_time_string(), message);
+  }
+}
+
+void tetj_purpose_end(struct tetj_handle *handle,
+                      unsigned int activity, unsigned int tpnumber)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "410|%u %u %s|IC End\n",
+            activity, tpnumber, get_current_time_string());
+  }
+}
+
+void tetj_result(struct tetj_handle *handle, 
+                 unsigned int activity, unsigned int tpnumber, 
+                 enum testcase_results result)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "220|%u %u %i %s|%s\n",
+            activity, tpnumber, result, get_current_time_string(),
+            get_result_string(result));
+  }
+}
+
+void tetj_testcase_info(struct tetj_handle *handle,
+                        unsigned int activity, unsigned int tpnumber,
+                        unsigned int context, unsigned int block,
+                        unsigned int sequence, char *message)
+{
+  if (handle)
+  {
+    fprintf(handle->journal, "520|%u %u %u %u %u|%s\n",
+            activity, tpnumber, context, block, sequence, message);
+  }
+}
diff --git a/lsbpkgchk/src/tests/tetj/tetj.h b/lsbpkgchk/src/tests/tetj/tetj.h
new file mode 100644 (file)
index 0000000..2d1a1fa
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef __TETJ_H
+#define __TETJ_H
+
+/* Interface for generating TET like report journals
+ *
+ * This intended to be a simple way of creating journals which
+ * can be analysed using standard TET journal tools without
+ * having to compile or link against the TET libraries.
+ * 
+ * (C) Copyright 2002 The Free Standards Group Inc
+ *
+ * 2002/03/19 Chris Yeoh, IBM
+ *
+ * This is Revision: 1.2 
+ * 
+ * Log: tetj.h,v 
+ * Revision 1.2  2002/04/29 03:54:50  cyeoh
+ * Adds function to add end marker for test purposes
+ * Adds IC start markers
+ *
+ * Revision 1.1  2002/03/19 06:07:49  cyeoh
+ * Adds simple interface for generating TET journals
+ *
+ *
+ */
+
+/* Handle for journal functions */
+struct tetj_handle;
+
+enum testcase_results
+{
+  TETJ_PASS,
+  TETJ_FAIL,
+  TETJ_UNRESOLVED,
+  TETJ_NOTINUSE,
+  TETJ_UNSUPPORTED,
+  TETJ_UNTESTED,
+  TETJ_UNINITIATED,
+  TETJ_UNREPORTED,
+  TETJ_WARNING = 101,
+  TETJ_FIP,
+  TETJ_NOTIMP,
+  TETJ_UNAPPROVE
+};
+
+/* Open journal */
+int tetj_start_journal(const char *pathname, struct tetj_handle **handle,
+                       char *command_run);
+/* Close journal */
+int tetj_close_journal(struct tetj_handle *handle);
+
+/* Add Config information */
+void tetj_add_config(struct tetj_handle *handle, char *message);
+
+/* Add controller error message */
+void tetj_add_controller_error(struct tetj_handle *handle, char *message);
+
+/* test case start */
+void tetj_testcase_start(struct tetj_handle *handle, 
+                         unsigned int activity, char *testcase, char *message);
+
+/* test case end */
+void tetj_testcase_end(struct tetj_handle *handle, 
+                       unsigned int activity, char *testcase, char *message);
+
+/* test purpose start */
+void tetj_purpose_start(struct tetj_handle *handle,
+                        unsigned int activity, unsigned int tpnumber, 
+                        char *message);
+
+/* test purpose end */
+void tetj_purpose_end(struct tetj_handle *handle,
+                      unsigned int activity, unsigned int tpnumber);
+
+/* Set testcase result */
+void tetj_result(struct tetj_handle *handle,
+                 unsigned int activity, unsigned int tpnumber, 
+                 enum testcase_results result);
+
+/* testcase info */
+void tetj_testcase_info(struct tetj_handle *handle,
+                        unsigned int activity, unsigned int tpnumber,
+                        unsigned int context, unsigned int block,
+                        unsigned int sequence, char *message);
+
+extern int tetj_activity_count;
+extern int tetj_tp_count;
+
+#endif
diff --git a/lsbpkgchk/src/tests/tetj/tetj.py b/lsbpkgchk/src/tests/tetj/tetj.py
new file mode 100755 (executable)
index 0000000..25e13f6
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+#
+# Interface for generating TET like report journals
+#
+# This intended to be a simple way of creating journals which
+# can be analysed using standard TET journal tools without
+# having to compile or link against the TET libraries.
+#
+# (C) Copyright 2002 The Free Standards Group, Inc.
+#
+# Python module converted from C version (tetj.c 1.3)
+# 2002/09/20 Mats Wichmann, Intel
+#
+# This is Revision: 1.1 
+#
+# Log: tetj.py,v 
+# Revision 1.1  2002/09/20 15:12:24  mwichmann
+# Initial converted version.  Includes a self-test harness.
+#
+#
+import sys, os, pwd, time
+
+TETJ_PASS = 0
+TETJ_FAIL = 1
+TETJ_UNRESOLVED = 2
+TETJ_NOTINUSE = 3
+TETJ_UNSUPPORTED = 4
+TETJ_UNTESTED = 5
+TETJ_UNINITIATED = 6
+TETJ_UNREPORTED = 7
+TETJ_WARNING = 101
+TETJ_FIP = 102
+TETJ_NOTIMP = 103
+TETJ_UNAPPROVE = 104
+
+result_codes = {
+    TETJ_PASS: "PASS",
+    TETJ_FAIL: "FAIL",
+    TETJ_UNRESOLVED: "UNRESOLVED",
+    TETJ_NOTINUSE: "NOTINUSE",
+    TETJ_UNSUPPORTED: "UNSUPPORTED",
+    TETJ_UNTESTED: "UNTESTED",
+    TETJ_UNINITIATED: "UNITIATED",
+    TETJ_UNREPORTED: "UNREPORTED",
+    TETJ_WARNING: "WARNING",
+    TETJ_FIP: "FIP",
+    TETJ_NOTIMP: "NOTIMP",
+    TETJ_UNAPPROVE: "UNAPPROVE",
+}
+
+class tetj_handle:
+    def __init__(self, journal):
+        self.journal = journal
+
+activity_count = 0
+tp_count = 0
+
+def get_current_time_string():
+    return time.strftime("%H:%M:%S")
+
+def start_journal(pathname, command_run):
+    try:
+        f = open(pathname, 'w')
+    except IOerror:
+        return None
+    handle = tetj_handle(f)
+
+    (sysname, nodename, release, version, machine) = os.uname()
+    datetime = time.strftime("%H:%M:%S %Y%m%d")
+    uid = os.getuid();
+    try:
+        pwent = pwd.getpwuid(uid);
+    except KeyError:
+        pwent = ""
+  
+    handle.journal.write("0|lsb-0.1 %s|User: %s (%i) TCC Start, Command line: %s\n" %
+          (datetime, pwent[0], uid, command_run))
+
+    handle.journal.write("5|%s %s %s %s %s|System Information\n" %
+          (sysname, nodename, release, version, machine))
+          
+    return handle
+
+def close_journal(handle):
+    if handle:
+        handle.journal.write("900|%s|TCC End\n" % get_current_time_string())
+        return handle.journal.close()
+    else:
+        return 0
+
+def add_config(handle, message):
+    if handle:
+        handle.journal.write("30||%s\n" % message)
+
+def add_controller_error(handle, message):
+    if handle:
+        handle.journal.write("50||%s\n" % message)
+
+def testcase_start(handle, activity, testcase, message):
+    if handle:
+        handle.journal.write("10|%u %s %s|TC Start%s\n" %
+            (activity, testcase, get_current_time_string(), message))
+
+def testcase_end(handle, activity, testcase, message):
+    if handle:
+        handle.journal.write("80|%u %s %s|TC End%s\n" %
+            (activity, testcase, get_current_time_string(), message))
+
+def purpose_start(handle, activity, tpnumber, message):
+    if (handle):
+        handle.journal.write("400|%u %u %s|IC Start\n" %
+            (activity, tpnumber, get_current_time_string()))
+        handle.journal.write("200|%u %u %s|%s\n" %
+            (activity, tpnumber, get_current_time_string(), message))
+
+def purpose_end(handle, activity, tpnumber):
+    if handle:
+        handle.journal.write("410|%u %u %s|IC End\n" %
+            (activity, tpnumber, get_current_time_string()))
+
+def result(handle, activity, tpnumber, result):
+    if handle:
+        code = result_codes.get(result, "UNKNOWN")
+        handle.journal.write("220|%u %u %i %s|%s\n" %
+            (activity, tpnumber, result, get_current_time_string(), code))
+
+def testcase_info(handle,activity,tpnumber,context,block,sequence,message):
+    if handle:
+        handle.journal.write("520|%u %u %u %u %u|%s\n" %
+            (activity, tpnumber, context, block, sequence, message))
+
+
+def _test():
+    # self-test code: exercise a bunch of the stuff,
+    # for now there's no feedback as to whether it came out right -
+    # just manually scan the journal.tetjtest file
+    teststuff = {
+        "red": TETJ_PASS,
+        "green": TETJ_FAIL,
+        "blue": TETJ_UNRESOLVED,
+        "white": TETJ_NOTINUSE,
+        "black": TETJ_UNSUPPORTED,
+        "purple": TETJ_UNTESTED,
+        "teal": TETJ_UNINITIATED,
+        "yellow": TETJ_UNREPORTED,
+        "orange": TETJ_WARNING,
+        "plum": TETJ_FIP,
+        "foxglove": TETJ_NOTIMP,
+        "alabaster": TETJ_UNAPPROVE
+    }
+    print "tetj.py: writing journal to journal.tetjtest"
+    journal = start_journal("journal.tetjtest", "tetjtest")
+    add_config(journal, "VSX_NAME=tetjtest unofficial")
+    activity_count = 1
+    testcase_start(journal, activity_count, "foo", "")
+    tp_count = 0
+    for (purpose, tpresult) in teststuff.items():
+        tp_count += 1
+        purpose_start(journal, activity_count, tp_count, purpose)
+        result(journal, activity_count, tp_count, tpresult)
+        purpose_end(journal, activity_count, tp_count)
+    testcase_end(journal, activity_count, "foo", "")
+    activity_count += 1
+    testcase_start(journal, activity_count, "bar", "")
+    for (purpose, tpresult) in teststuff.items():
+        tp_count += 1
+        purpose_start(journal, activity_count, tp_count, purpose)
+        result(journal, activity_count, tp_count, tpresult)
+        purpose_end(journal, activity_count, tp_count)
+    testcase_end(journal, activity_count, "bar", "")
+    close_journal(journal)
+
+if __name__ == "__main__":
+    _test()