From ad513051bd51228aa506e3d33adfff37d4d1eef7 Mon Sep 17 00:00:00 2001 From: jbj Date: Wed, 23 Oct 2002 15:39:41 +0000 Subject: [PATCH] Initial revision CVS patchset: 5803 CVS date: 2002/10/23 15:39:41 --- lsbpkgchk/Licence | 71 ++ lsbpkgchk/Makefile | 16 + lsbpkgchk/README | 16 + lsbpkgchk/src/tests/pkgchk/.cvsignore | 1 + lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1 | 25 + lsbpkgchk/src/tests/pkgchk/makefile | 24 + lsbpkgchk/src/tests/pkgchk/pkgchk.c | 89 +++ lsbpkgchk/src/tests/rpmchk/.cvsignore | 1 + lsbpkgchk/src/tests/rpmchk/archive.c | 333 +++++++++ lsbpkgchk/src/tests/rpmchk/fhs.c | 38 ++ lsbpkgchk/src/tests/rpmchk/hdr.c | 98 +++ lsbpkgchk/src/tests/rpmchk/idxtag.c | 1174 ++++++++++++++++++++++++++++++++ lsbpkgchk/src/tests/rpmchk/idxtbl.c | 75 ++ lsbpkgchk/src/tests/rpmchk/lead.c | 55 ++ lsbpkgchk/src/tests/rpmchk/makefile | 33 + lsbpkgchk/src/tests/rpmchk/md5.h | 54 ++ lsbpkgchk/src/tests/rpmchk/md5c.c | 349 ++++++++++ lsbpkgchk/src/tests/rpmchk/mktaghdr | 36 + lsbpkgchk/src/tests/rpmchk/mktagtbl | 47 ++ lsbpkgchk/src/tests/rpmchk/rpmchk.c | 16 + lsbpkgchk/src/tests/rpmchk/rpmchk.h | 213 ++++++ lsbpkgchk/src/tests/rpmchk/rpmtag.h | 68 ++ lsbpkgchk/src/tests/rpmchk/tagfuncs.h | 61 ++ lsbpkgchk/src/tests/rpmchk/test.c | 35 + lsbpkgchk/src/tests/rpmchk/util.c | 63 ++ lsbpkgchk/src/tests/rpmchk/vals.c | 47 ++ lsbpkgchk/src/tests/tetj/Makefile | 14 + lsbpkgchk/src/tests/tetj/tetj.c | 224 ++++++ lsbpkgchk/src/tests/tetj/tetj.h | 89 +++ lsbpkgchk/src/tests/tetj/tetj.py | 174 +++++ 30 files changed, 3539 insertions(+) create mode 100644 lsbpkgchk/Licence create mode 100644 lsbpkgchk/Makefile create mode 100644 lsbpkgchk/README create mode 100644 lsbpkgchk/src/tests/pkgchk/.cvsignore create mode 100644 lsbpkgchk/src/tests/pkgchk/lsbpkgchk.1 create mode 100644 lsbpkgchk/src/tests/pkgchk/makefile create mode 100644 lsbpkgchk/src/tests/pkgchk/pkgchk.c create mode 100644 lsbpkgchk/src/tests/rpmchk/.cvsignore create mode 100644 lsbpkgchk/src/tests/rpmchk/archive.c create mode 100644 lsbpkgchk/src/tests/rpmchk/fhs.c create mode 100644 lsbpkgchk/src/tests/rpmchk/hdr.c create mode 100644 lsbpkgchk/src/tests/rpmchk/idxtag.c create mode 100644 lsbpkgchk/src/tests/rpmchk/idxtbl.c create mode 100644 lsbpkgchk/src/tests/rpmchk/lead.c create mode 100644 lsbpkgchk/src/tests/rpmchk/makefile create mode 100644 lsbpkgchk/src/tests/rpmchk/md5.h create mode 100644 lsbpkgchk/src/tests/rpmchk/md5c.c create mode 100755 lsbpkgchk/src/tests/rpmchk/mktaghdr create mode 100755 lsbpkgchk/src/tests/rpmchk/mktagtbl create mode 100644 lsbpkgchk/src/tests/rpmchk/rpmchk.c create mode 100644 lsbpkgchk/src/tests/rpmchk/rpmchk.h create mode 100644 lsbpkgchk/src/tests/rpmchk/rpmtag.h create mode 100644 lsbpkgchk/src/tests/rpmchk/tagfuncs.h create mode 100644 lsbpkgchk/src/tests/rpmchk/test.c create mode 100644 lsbpkgchk/src/tests/rpmchk/util.c create mode 100644 lsbpkgchk/src/tests/rpmchk/vals.c create mode 100644 lsbpkgchk/src/tests/tetj/Makefile create mode 100644 lsbpkgchk/src/tests/tetj/tetj.c create mode 100644 lsbpkgchk/src/tests/tetj/tetj.h create mode 100755 lsbpkgchk/src/tests/tetj/tetj.py diff --git a/lsbpkgchk/Licence b/lsbpkgchk/Licence new file mode 100644 index 0000000..b5796cb --- /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 0000000..4e55a20 --- /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 0000000..3f75f0d --- /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 0000000..23db96b --- /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 0000000..8b18b7d --- /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 . +.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 0000000..6406cea --- /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 0000000..eb66cd7 --- /dev/null +++ b/lsbpkgchk/src/tests/pkgchk/pkgchk.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#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 0000000..d607e9f --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/fhs.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#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 0000000..525cba3 --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/hdr.c @@ -0,0 +1,98 @@ +#include +#include +#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 0000000..0b81689 --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/idxtag.c @@ -0,0 +1,1174 @@ +#include +#include +#include +#include +#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;ioffset); +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;icount);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;icount);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;icount);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;ioffset); +hcount=ntohl(hidx->count); +filemodes=(short *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +filerdevs=(short *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +filetimes=(int *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +filemd5s=(char *)(file1->storeaddr+hoffset); +name=filemd5s; +for(i=0;ioffset); +hcount=ntohl(hidx->count); +filelinktos=(char *)(file1->storeaddr+hoffset); +name=filelinktos; +for(i=0;ioffset); +hcount=ntohl(hidx->count); +fflags=(int *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +fileusernames=(char *)(file1->storeaddr+hoffset); +name=fileusernames; +for(i=0;ioffset); +hcount=ntohl(hidx->count); +filegroupnames=(char *)(file1->storeaddr+hoffset); +name=filegroupnames; +for(i=0;ioffset); +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;ioffset); +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;ioffset); +hcount=ntohl(hidx->count); +name=file1->storeaddr+hoffset; +for(i=0;ioffset); +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;ioffset); +hcount=ntohl(hidx->count); +name=(char *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +text=(char *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +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;ioffset); +hcount=ntohl(hidx->count); +fileinodes=(uint32_t *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +filelangs=(char *)(file1->storeaddr+hoffset); +name=filelangs; +for(i=0;ioffset); +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;ioffset); +hcount=ntohl(hidx->count); +dirindicies=(int *)(file1->storeaddr+hoffset); +for(i=0;ioffset); +hcount=ntohl(hidx->count); +basenames=(char **)malloc(hcount*sizeof(char *)); +name=file1->storeaddr+hoffset; +for(i=0;ioffset); +hcount=ntohl(hidx->count); +numdirnames=hcount; +dirnames=(char **)malloc(hcount*sizeof(char *)); +name=file1->storeaddr+hoffset; +for(i=0;ioffset); +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;ioffset); +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 0000000..3113471 --- /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 0000000..4a9f1c6 --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/lead.c @@ -0,0 +1,55 @@ +#include +#include +#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 0000000..3281881 --- /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 0000000..d07667e --- /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 0000000..378360f --- /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 0000000..4dc4830 --- /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 0000000..946d69b --- /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 0000000..a18aba2 --- /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 0000000..043b928 --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/rpmchk.h @@ -0,0 +1,213 @@ +#ifndef _RPMCHK_H +#define _RPMCHK_H + +#include +#include +#include + +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 0000000..a5d92c1 --- /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 0000000..9fa91d2 --- /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 0000000..db5aa77 --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/test.c @@ -0,0 +1,35 @@ +#include +#include +#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 0000000..d27b9c9 --- /dev/null +++ b/lsbpkgchk/src/tests/rpmchk/util.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#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 0000000..d536d96 --- /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 0000000..12c8b76 --- /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 0000000..29b6d9c --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(¤t_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(¤t_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 0000000..2d1a1fa --- /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 0000000..25e13f6 --- /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() -- 2.7.4