summaryrefslogtreecommitdiff
path: root/lsbpkgchk
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2002-10-23 15:39:41 +0000
committerjbj <devnull@localhost>2002-10-23 15:39:41 +0000
commitad513051bd51228aa506e3d33adfff37d4d1eef7 (patch)
treec4c1cb6b0f8d9d691312089b392d0caa585217d0 /lsbpkgchk
parent30b650580233b357cc7e68e95accc9db4186e5b5 (diff)
downloadrpm-ad513051bd51228aa506e3d33adfff37d4d1eef7.tar.gz
Initial revision
CVS patchset: 5803 CVS date: 2002/10/23 15:39:41
Diffstat (limited to 'lsbpkgchk')
-rw-r--r--lsbpkgchk/Licence71
-rw-r--r--lsbpkgchk/Makefile16
-rw-r--r--lsbpkgchk/README16
-rw-r--r--lsbpkgchk/src/tests/pkgchk/.cvsignore1
-rw-r--r--lsbpkgchk/src/tests/pkgchk/lsbpkgchk.125
-rw-r--r--lsbpkgchk/src/tests/pkgchk/makefile24
-rw-r--r--lsbpkgchk/src/tests/pkgchk/pkgchk.c89
-rw-r--r--lsbpkgchk/src/tests/rpmchk/.cvsignore1
-rw-r--r--lsbpkgchk/src/tests/rpmchk/archive.c333
-rw-r--r--lsbpkgchk/src/tests/rpmchk/fhs.c38
-rw-r--r--lsbpkgchk/src/tests/rpmchk/hdr.c98
-rw-r--r--lsbpkgchk/src/tests/rpmchk/idxtag.c1174
-rw-r--r--lsbpkgchk/src/tests/rpmchk/idxtbl.c75
-rw-r--r--lsbpkgchk/src/tests/rpmchk/lead.c55
-rw-r--r--lsbpkgchk/src/tests/rpmchk/makefile33
-rw-r--r--lsbpkgchk/src/tests/rpmchk/md5.h54
-rw-r--r--lsbpkgchk/src/tests/rpmchk/md5c.c349
-rwxr-xr-xlsbpkgchk/src/tests/rpmchk/mktaghdr36
-rwxr-xr-xlsbpkgchk/src/tests/rpmchk/mktagtbl47
-rw-r--r--lsbpkgchk/src/tests/rpmchk/rpmchk.c16
-rw-r--r--lsbpkgchk/src/tests/rpmchk/rpmchk.h213
-rw-r--r--lsbpkgchk/src/tests/rpmchk/rpmtag.h68
-rw-r--r--lsbpkgchk/src/tests/rpmchk/tagfuncs.h61
-rw-r--r--lsbpkgchk/src/tests/rpmchk/test.c35
-rw-r--r--lsbpkgchk/src/tests/rpmchk/util.c63
-rw-r--r--lsbpkgchk/src/tests/rpmchk/vals.c47
-rw-r--r--lsbpkgchk/src/tests/tetj/Makefile14
-rw-r--r--lsbpkgchk/src/tests/tetj/tetj.c224
-rw-r--r--lsbpkgchk/src/tests/tetj/tetj.h89
-rwxr-xr-xlsbpkgchk/src/tests/tetj/tetj.py174
30 files changed, 3539 insertions, 0 deletions
diff --git a/lsbpkgchk/Licence b/lsbpkgchk/Licence
new file mode 100644
index 000000000..b5796cb64
--- /dev/null
+++ b/lsbpkgchk/Licence
@@ -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
index 000000000..4e55a20d0
--- /dev/null
+++ b/lsbpkgchk/Makefile
@@ -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
index 000000000..3f75f0dea
--- /dev/null
+++ b/lsbpkgchk/README
@@ -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
index 000000000..23db96b4b
--- /dev/null
+++ b/lsbpkgchk/src/tests/pkgchk/.cvsignore
@@ -0,0 +1 @@
+pkgchk
diff --git a/lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1 b/lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1
new file mode 100644
index 000000000..8b18b7d6e
--- /dev/null
+++ b/lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1
@@ -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
index 000000000..6406cea2d
--- /dev/null
+++ b/lsbpkgchk/src/tests/pkgchk/makefile
@@ -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
index 000000000..eb66cd75d
--- /dev/null
+++ b/lsbpkgchk/src/tests/pkgchk/pkgchk.c
@@ -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
index 000000000..9daeafb98
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/.cvsignore
@@ -0,0 +1 @@
+test
diff --git a/lsbpkgchk/src/tests/rpmchk/archive.c b/lsbpkgchk/src/tests/rpmchk/archive.c
new file mode 100644
index 000000000..d178c5dc2
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/archive.c
@@ -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
index 000000000..d607e9f74
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/fhs.c
@@ -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
index 000000000..525cba3bb
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/hdr.c
@@ -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
index 000000000..0b816895a
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/idxtag.c
@@ -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
index 000000000..311347127
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/idxtbl.c
@@ -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
index 000000000..4a9f1c607
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/lead.c
@@ -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
index 000000000..32818817c
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/makefile
@@ -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
index 000000000..d07667e2e
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/md5.h
@@ -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
index 000000000..378360f44
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/md5c.c
@@ -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
index 000000000..4dc48304b
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/mktaghdr
@@ -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
index 000000000..946d69b97
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/mktagtbl
@@ -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
index 000000000..a18aba2ed
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/rpmchk.c
@@ -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
index 000000000..043b9284f
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/rpmchk.h
@@ -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
index 000000000..a5d92c160
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/rpmtag.h
@@ -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
index 000000000..9fa91d2b3
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/tagfuncs.h
@@ -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
index 000000000..db5aa7709
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/test.c
@@ -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
index 000000000..d27b9c945
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/util.c
@@ -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
index 000000000..d536d9673
--- /dev/null
+++ b/lsbpkgchk/src/tests/rpmchk/vals.c
@@ -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
index 000000000..12c8b76a2
--- /dev/null
+++ b/lsbpkgchk/src/tests/tetj/Makefile
@@ -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
index 000000000..29b6d9cc9
--- /dev/null
+++ b/lsbpkgchk/src/tests/tetj/tetj.c
@@ -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
index 000000000..2d1a1fae6
--- /dev/null
+++ b/lsbpkgchk/src/tests/tetj/tetj.h
@@ -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
index 000000000..25e13f6a1
--- /dev/null
+++ b/lsbpkgchk/src/tests/tetj/tetj.py
@@ -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()