summaryrefslogtreecommitdiff
path: root/tools/javadeps.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/javadeps.c')
-rw-r--r--tools/javadeps.c1288
1 files changed, 0 insertions, 1288 deletions
diff --git a/tools/javadeps.c b/tools/javadeps.c
deleted file mode 100644
index 9d15787e9..000000000
--- a/tools/javadeps.c
+++ /dev/null
@@ -1,1288 +0,0 @@
-/*
-RPM and it's source code are covered under two separate licenses.
-
-The entire code base may be distributed under the terms of the GNU General
-Public License (GPL), which appears immediately below. Alternatively,
-all of the source code in the lib subdirectory of the RPM source code
-distribution as well as any code derived from that code may instead be
-distributed under the GNU Library General Public License (LGPL), at the
-choice of the distributor. The complete text of the LGPL appears
-at the bottom of this file.
-
-This alternatively is allowed to enable applications to be linked against
-the RPM library (commonly called librpm) without forcing such applications
-to be distributed under the GPL.
-
-Any questions regarding the licensing of RPM should be addressed to
-marc@redhat.com and ewt@redhat.com.
-*/
-
-/*
- Simple progam for pullng all the referenced java classes out of a
- class file. Java files are supposed to be platform independent, so
- this program should work on all platforms. This code is based on
- the information found in:
-
- "Java Virtual Machine" by Jon Meyer & Troy Downing.
- O'Reilly & Associates, INC. (First Edition, March 1997)
- ISBN: 1-56592-194-1
-
- Jonathan Ross, Ken Estes
- Mail.com
- */
-
-
-/*
- Remember that:
-
- JAR consists of a zip archive, as defined by PKWARE, containing
- a manifest file and potentially signature files, as defined in
- the Manifest and Signature specification. So we use infozip's
- 'unzip -p' found at http://www.cdrom.com/pub/infozip/.
-
- Additional documentation, about this fact, at:
-
- http://java.sun.com/products/jdk/1.1/docs/guide/jar/jarGuide.html
- http://java.sun.com/products/jdk/1.2/docs/guide/jar/jarGuide.html
-
- http://java.sun.com/products/jdk/1.1/docs/guide/jar/manifest.html
- http://java.sun.com/products/jdk/1.2/docs/guide/jar/manifest.html
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <netdb.h>
-#include <rpm/rpmutil.h>
-#include <ctype.h>
-#include "debug.h"
-
-/*---------typedefs---------*/
-
-
-/* The symbol table is a waste of memory..
- but it's easy to code! */
-
-typedef struct {
- short poolSize;
- char **stringList;
- short *classRef;
- short *typeRef;
-} symbolTable_t;
-
-
-/*---------Global Variables, in all caps---------*/
-
-/*name of this program*/
-const char *PROGRAM_NAME=0;
-
-/*name of the current class file*/
-const char *FILE_NAME=0;
-
-/*the name of the last class file seen*/
-char *CLASS_NAME=0;
-
-/*The string to put before each line,
- this is a formatted version of CLASS_NAME */
-char *OUTPUT_PREFIX=0;
-
-/*arguments chosen*/
-int ARG_PROVIDES=0;
-int ARG_REQUIRES=0;
-int ARG_RPMFORMAT=0;
-int ARG_DEPSFORMAT=0;
-int ARG_KEYWORDS=0;
-int ARG_STARPROV=0;
-
-/*keywords found in class file*/
-char *KEYWORD_VERSION=0;
-char *KEYWORD_REVISION=0;
-char *KEYWORD_EPOCH=0;
-
-/*
-
- Quantify says over 80 percent of the time of the program is spent
- in printf (and the functions it calls) AND I verified that only
- about a quarter of the classes found in the dependency analysis are
- unique. After the change no function used more then 26% of the over
- all time.
-
- I implement a simple mechanism to remove most duplicate
- dependencies. The print_table is a table of string, with
- duplicates, which are to be printed. Just before the program
- exists it is sorted and all unique entries are printed. If it
- fills up during then it is flushed using the same technique as
- above.
-
- The functions which manipulate the table are:
- void print_table_flush(void)
- void print_table_add(char *str)
-
-*/
-
-
-#define MAX_PRINT_TABLE 10000
-char *PRINT_TABLE[MAX_PRINT_TABLE];
-int SIZE_PRINT_TABLE;
-
-/*--------- declare all functions ---------*/
-
-void usage (void);
-void outofmemory(void);
-void die(const char *format, ...);
-size_t my_fread(void *ptr, size_t size, size_t nitems, FILE *stream);
-void check_range(short entryNum, short value, short poolSize);
-char *is_lower_equal (char *string, const char *pattern);
-int findJavaMagic (FILE *fileHandle);
-int my_strcmp (const void *a, const void *b);
-void print_table_flush(void);
-void print_table_add(char *str);
-char *formatClassName(char *pSomeString, char terminator, char print_star);
-void dumpRefType(char *pSomeString);
-void genSymbolTable (FILE *fileHandle, symbolTable_t *symbolTable);
-void freeSymbolTable (symbolTable_t *symbolTable);
-char *findClassName (FILE *fileHandle, symbolTable_t *symbolTable);
-void dumpProvides(char *className);
-void dumpRequires(symbolTable_t *symbolTable);
-void processJavaFile (FILE *fileHandle);
-
-/*--------- functions ---------*/
-
-void
-usage (void)
-{
- printf("NAME:\n\tjavadeps - Examine Java class files and\n"
- "\t\t\treturn information about their dependencies.\n\n");
- printf("USAGE:\n");
- printf("\t javadeps { --provides | --requires } \n"
- "\t\t [--rpmformat] [--depsformat] [--keywords] \n"
- "\t\t [--] classfile-name ... \n\n"
- "\t javadeps [--help]\n\n");
- printf("\n\n");
- printf("DESCRIPTION:\n\n");
- printf("List the dependencies or the fully qualified class names, of the \n"
- "classfiles listed on the command line. \n\n");
- printf("OPTIONS:\n\n");
- printf("--requires For each class files listed in the arguments,\n"
- " -r print the list of class files that would be\n"
- " required to run these java programs. This does not \n"
- " include anyting instantiated by reflection.\n\n");
- printf("--provides For each class files listed in the arguments, \n"
- " -p Print the fully qualified java classes,\n"
- " that they provide.\n\n");
- printf("--rpmformat Format the output to match that used by RPM's \n"
- " -F (Red Hat Package Manager) dependency analysis \n"
- " database. The default is not --rpmformat.\n\n");
- printf("--depsformat print the name of the class which \n"
- " -d This is mostly used in conjunctions with --requires \n"
- " to list the class file dependencies in a format "
- " similar to traditional Makefile dependencies. The "
- " default is not --depsformat.\n\n");
- printf("--keywords Make use of any keywords embeded in the classfile.\n"
- " -k The default is not --keyword.\n\n");
- printf("--starprov Add the star notation provides to the provides list.\n"
- " -s The default is not --starprov. This is only for use\n"
- " with (Sun) jhtml dependencies, and since jhtml is \n"
- " deprecated so is this option.\n\n");
- printf("--help Display this page and exit.\n\n");
- printf("-- This stops the processing of arguments, making it \n"
- " easier for users to have filenames like '--keywords',\n"
- " without the command line parser getting confused.\n\n");
- printf("\n\n");
- printf("If any of the class file names in the argument list is '-' then\n"
- "<stdin> will be read instead of reading from a file. The\n"
- "contents of <stdin> should be the contents of a class file and \n"
- "not a list of class files to read. It is assumed that when run \n"
- "with '-', this program is in a pipeline preceded by the \n"
- "command 'unzip -p filename.jar' so that <stdin> may contain\n"
- "the contents of several classfiles concatenated together.\n");
- printf("\n\n");
- printf("If --keywords is specified then the following strings are \n"
- "searched for (case insensitive) in the class file string table\n"
- "and, if a string is found with a prefix matching the keyword then \n"
- "the dependencies are changed accordingly. There may be multiple \n"
- "string tables entries prefixed with RPM_Provides and RPM_Requires. \n"
- "This would indicate that the dependency is the union\n"
- "of all entries.\n"
- "\n\n"
- "Keyword List:\n\n"
- "'$Revision: ' This RCS/CVS compatible keyword is assumed to \n"
- " contain the version number of the class file \n"
- " it is found in. Care should be taken with this\n"
- " option as RPM's notion of which version is later\n"
- " may not corrispond with your own, especially\n"
- " if you use branches. This keyword\n"
- " only effects the output of --provides and only\n"
- " when RPM_Version is not defined.\n\n"
- "'RPM_Version: ' This is an alternative method of specifying the\n"
- " version number of the class. It will override\n"
- " $Revision if set. This keyword only effects\n"
- " the output of --provides \n\n"
- "'RPM_Epoch: ' This string contains the epoch to use with the \n"
- " version number stored in Revision. If not \n"
- " specified, the epoch is assumed to be zero.\n"
- " This keyword only effects the output of\n "
- " --provides and only when $Revision number is\n"
- " used.\n\n"
- "'RPM_Provides: ' This string lists additional capabilities\n"
- " provided by the java class. The string should\n"
- " be a white space ([\\t\\v\\n\\r\\f\\ ])\n"
- " separated list of dependency strings. Each\n"
- " dependency string must be of the same format as\n"
- " would be valid in the Requires or Provides line\n"
- " of the specfile. This keyword only effects the\n"
- " output of --provides.\n\n"
- "'RPM_Requires: ' This string lists additional requirements of\n"
- " the java class. The string should be a white \n"
- " space ([\\t \v\\n\\r\\f\\ ]) separated list of \n"
- " dependency strings. Each dependency string must\n"
- " be of the same format as would be valid in the \n"
- " Requires or Provides line of the specfile. This\n"
- " keyword only effects the output of --requires.\n "
- " \n\n"
- "Note that there is no means of setting the release number. This\n"
- "is necessary because release numbers are incremented when the\n"
- "source does not change but the package needs to be rebuilt. So\n"
- "relase numbers can not be stored in the source. The release is\n"
- "assumed to be zero. \n\n"
- "");
- printf("EXAMPLES (Java Keywords): \n\n"
- "\t public static final String REVISION = \"$Revision: 2.12 $\";\n"
- "\t public static final String EPOCH = \"4\";\n"
- "\t public static final String REQUIRES = \"RPM_Requires: "
- "java(gnu.regexp.RE) java(com.ibm.site.util.Options)>=1.5\";\n"
- "");
- printf("\n\n");
- printf("EXAMPLES (Arguments): \n\n"
- "\tjavadeps --requires -- filename.class\n\n"
- "\tjavadeps --provides -- filename.class\n\n"
- "\tjavadeps --help\n\n"
- "\n"
- "\tjavadeps --requires --rpmformat --keywords -- filename.class\n\n"
- "\tjavadeps --requires --depsformat -- filename.class\n\n"
- "\tjavadeps --requires -- filename1.class filename2.class\n\n"
- "\tcat filename2.class | javadeps --requires -- filename1.class -\n\n"
- "\tunzip -p filename.jar | javadeps --requires -- - \n\n"
- "");
- printf("This program is distributed with RPM the Redhat Package \n"
- "Managment system. Further information about RPM can be found at \n"
- "\thttp://www.rpm.org/\n\n");
- printf("\n\n");
- exit(-1);
-}
-
-RPM_GNUC_NORETURN
-void outofmemory(void) {
-
- /* Its doubtful we could do a printf if there is really a memory
- issue but at least halt the program */
-
- fprintf(stderr, "Could not allocate memory\n");
- exit(-1);
-}
-
-RPM_GNUC_NORETURN
-void die(const char *format, ...) {
- /* Most errors are fatal.
- This function throws a fatal error and
- accepts arguments like printf does*/
-
- char *newformat = NULL, *newmsg = NULL;
- va_list ap;
-
- if (
- !(newformat = (char*) malloc(1024)) ||
- !(newmsg = (char*) malloc(1024))
- )
- outofmemory();
-
- /* Rewrite format line, to include additional information. The
- format line we chose depends on how much information is availible
- at the time of the error. Display the maximum ammount of
- information. */
-
- /* notice the FILE_NAME is useless for jar files. We would want to
- print the name of the classfile which caused the error. That
- is hard since we only know that name when we are done parsing
- the file, and most errors will occur before that.*/
-
- if ( (!FILE_NAME) ) {
-
- sprintf (newformat, "\n%s: %s",
- PROGRAM_NAME, format);
-
- } else if ( (FILE_NAME) && (!CLASS_NAME) ) {
-
- sprintf (newformat, "\n%s: Java classfile: %s, %s",
- PROGRAM_NAME, FILE_NAME, format);
-
- } else if (CLASS_NAME) {
- sprintf (newformat, "\n%s: Java classfile: %s, classname: %s, %s",
- PROGRAM_NAME, FILE_NAME, CLASS_NAME, format);
- }
-
- va_start(ap, format);
- vsprintf (newmsg, newformat, ap);
- va_end(ap);
-
- /* print error to where it needs to go:
- stdout, stderr, or syslog
- */
-
- fprintf(stderr, "%s", newmsg);
-
- free(newformat);
- free(newmsg);
-
- exit(-1);
-}
-
-
-/* wrap fread for safety. It is a fatal error to get an unexpected
- EOF inside a class file. */
-
-size_t my_fread(void *ptr, size_t size, size_t nitems, FILE *stream) {
- size_t rc=0;
- /*these variables are helpful in the debugger*/
- int eof=0;
- int error=0;
-
-
- rc = fread(ptr, size, nitems, stream);
- if ( (size!=0) && (rc == 0) ) {
- eof = feof(stream);
- error = ferror(stream);
- die("Error reading from file, or unexpected EOF\n");
- }
- return rc;
-}
-
-
-void check_range(short entryNum, short value, short poolSize) {
-
- if (value > poolSize) {
- die("Symbol Table Entry Number: %d, Value: %d, "
- "is out of range of the constant pool. Pool Size: %d\n",
- entryNum, value, poolSize);
- }
- return ;
-}
-
-
-
-/* If lower case conversion of string is equal to pattern return a
- pointer into string, just after the match. If the string does not
- patch the pattern the null pointer is returned. This does not
- change string.
-
- This is similar to strcasecmp, but I expect my patterns to be a
- prefix of my strings. */
-
-char
-*is_lower_equal (char *string, const char *pattern)
-{
-
- while ( (tolower(*string) == *pattern) &&
- *string && *pattern ) {
- string++;
- pattern++;
- }
-
- if ( *pattern == 0 ) {
- return string;
- }
-
- return NULL;
-}
-
-
-/*
- Read fileHandle until we find the next instance of the Java
- Classfile magic number indicating a java file or find EOF or
- fileread error. Since we are reading from stdin which may contain
- the concatination of many class files we can not be sure that the
- magic number will be the first few bytes.
-
- Return 1 on success 0 on failure. */
-
-#define mod4(num) ( (num) & 3 )
-
-
-int findJavaMagic (FILE *fileHandle)
-{
- int offset=0;
- int foundMagic = 0;
- size_t rc;
-
- /* what were looking for */
- unsigned char magicInt[4] = {0xCA, 0xFE, 0xBA, 0xBE};
- /*the hex reads in decimal: 202 254 186 190 */
-
- /* a circular buffer indicating the last few bytes we read */
- unsigned char buffer[4] = {0};
-
- foundMagic = 0;
- while( !foundMagic ) {
-
- rc = fread(&buffer[offset], 1, 1, fileHandle);
- if ( !rc ) {
-
- /* Either this was not a java file or we were given a jar file
- and have already found the last java file in it.*/
-
- if ( feof(fileHandle) ) {
- return 0;
- }
-
- if ( ferror(fileHandle) ) {
- die ("Error reading character from file.\n");
- };
-
- }
-
- /* offset points to the most recent char we read so offest+1
- points to the oldest char we saved. */
-
- foundMagic = (
- (magicInt[0] == buffer[mod4(offset+1)]) &&
- (magicInt[1] == buffer[mod4(offset+2)]) &&
- (magicInt[2] == buffer[mod4(offset+3)]) &&
- (magicInt[3] == buffer[mod4(offset+0)]) &&
- 1
- );
-
- offset = mod4(offset+1);
-
- } /*end while*/
-
- return foundMagic;
-}
-
-#undef mod4
-
-
-int
-my_strcmp (const void *a, const void *b) {
-char **a1; char **b1;
-int ret;
-
-a1 = (char **)a;
-b1 = (char **)b;
-ret = strcmp(*a1,*b1);
- return ret;
-}
-
-/* print the unique strings found in PRINT_TABLE and clear it out */
-
-void
-print_table_flush(void) {
- int i;
- char *last_string;
-
- if (!SIZE_PRINT_TABLE) {
- return ;
- }
-
- /* The qsort line gives a warning on some unicies who insist that
- strcmp takes arguments of type pointers to void not the
- traditional pointers to char. */
-
- qsort( (void *) PRINT_TABLE, (size_t) SIZE_PRINT_TABLE,
- sizeof(char *), &my_strcmp);
-
- printf("%s\n",PRINT_TABLE[0]);
- last_string = PRINT_TABLE[0];
- PRINT_TABLE[0] = NULL;
-
- for (i = 1; i < SIZE_PRINT_TABLE; i++) {
- if ( strcmp(last_string, PRINT_TABLE[i]) ){
- printf("%s\n",PRINT_TABLE[i]);
- free(last_string);
- last_string = PRINT_TABLE[i];
- } else {
- free(PRINT_TABLE[i]);
- }
- PRINT_TABLE[i] = NULL;
- }
-
- free(last_string);
- SIZE_PRINT_TABLE = 0;
- return ;
-}
-
-
-/* add an element to PRINT_TABLE for later printing to stdout. We do
- not make a copy of the string so each string must be unique,
- (different calls must pass pointers to different areas of memory)
- and the string must not be freed anywhere else in the code and the
- string must be from memory which can be freed.*/
-
-void
-print_table_add(char *str) {
-
- if (SIZE_PRINT_TABLE == MAX_PRINT_TABLE) {
- print_table_flush();
- }
-
- if (OUTPUT_PREFIX) {
- char *new_str;
-
- new_str= (char*) malloc(strlen(OUTPUT_PREFIX)+strlen(str)+1);
- if (!new_str){
- outofmemory();
- }
-
- new_str[0]='\0';
- strcat(new_str,OUTPUT_PREFIX);
- strcat(new_str,str);
- free(str);
- str=new_str;
- }
-
- PRINT_TABLE[SIZE_PRINT_TABLE] = str;
- SIZE_PRINT_TABLE++;
- return ;
-}
-
-
-static void
-print_list(char *in_string) {
-
- /* This function is no longer needed due to fixes in RPM's
- processing of dependencies. Keep the code until I get a chance
- to use RPM3.0 personally */
-
- if (in_string) {
- printf("%s\n", in_string);
- }
-
-/*
- Old function did:
-
- Given a list separated by whitespace, put each element in the print
- table with an added "\n" */
-
- /*
- char *WhiteSpace_Set = "\t\v\n\r\f ";
- char *newEnd, *out_string;
- int copy_len;
-
- in_string += strspn(in_string, WhiteSpace_Set);
-
- while (*in_string) {
- newEnd = strpbrk(in_string, WhiteSpace_Set);
-
- if (newEnd) {
- copy_len = newEnd-in_string;
- } else {
- if (*in_string) {
- copy_len = strlen(in_string);
- } else {
- copy_len = 0;
- }
- }
-
- out_string = malloc(copy_len+10);
- if ( !out_string ) {
- outofmemory();
- }
- out_string[0]= '\0';
-
- if (copy_len) {
- strncat(out_string, in_string, copy_len);
- in_string+=copy_len;
- strcat(out_string, "\n");
- print_table_add(out_string);
- }
-
- in_string += strspn(in_string+copy_len, WhiteSpace_Set);
- }
-
- */
- return ;
-}
-
-
-/* Print a properly formatted java class name, and returns the length
- of the class string . Do not print \n here as we may wish to
- append the version number IFF we are printing the name of this classfile
-
- We also provide the class with the leaf node replaced with '*'.
- This would not be necessary if we only had to worry about java
- Class files. However our parsing of jhtml files depends on this
- information. This is deprecated since jhtml is deprecated and
- this method allows for very inaccurate dependencies.
-
- Also users may wish to refer to dependencies using star notation
- (though this would be less accurate then explicit dependencies
- since any leaf class will satify a star dependency). */
-
-char
-*formatClassName(char *in_string, char terminator,
- char print_star)
-{
- char *leaf_class=0, *out_string=0;
- char *ClassName_Break_Set=0;
-
-
- out_string = (char*) malloc(strlen(in_string) + 10);
- if ( !out_string ) {
- outofmemory();
- }
- out_string[0]= '\0';
-
- /*these characters end the current parse of the string in function
- formatClassName.*/
-
- ClassName_Break_Set = (char*) malloc(3);
- if ( !ClassName_Break_Set ) {
- outofmemory();
- }
- ClassName_Break_Set[0] = '/';
- /*terminator can be '\0' this must go after '/'*/
- ClassName_Break_Set[1] = terminator;
- ClassName_Break_Set[2] = '\0';
-
- if(ARG_RPMFORMAT) {
- strcat(out_string, "java(");
- }
- if (print_star) {
- /* print the path to the leaf class but do not print the leaf
- class, stop at the last '/' we fix this back below*/
- leaf_class = strrchr(in_string, '/');
- if (leaf_class) {
- leaf_class[0] = terminator;
- }
- }
-
- while (*in_string != terminator) {
- char *newEnd=0;
- int copy_len;
-
- /* handle the break_set */
-
- if (in_string[0] == '\0' ) {
- die("Classname does not terminate with: '%c', '%s'\n",
- terminator, in_string);
- } else {
- if (in_string[0] == '/' ) {
- /* convert '/' to '.' */
- strcat(out_string, ".");
- in_string++;
- }
- }
-
- newEnd = strpbrk(in_string, ClassName_Break_Set);
-
- if (newEnd) {
- copy_len = newEnd-in_string;
- } else {
- if (terminator == '\0') {
- copy_len = strlen(in_string);
- } else {
- copy_len = 0;
- }
- }
-
- /* handle upto but not including the break_set*/
- if (copy_len) {
- strncat(out_string, in_string, copy_len);
- in_string+=copy_len;
- }
-
- } /*end while*/
-
- if (leaf_class) {
- /* print the star and fix the leaf class*/
- strcat(out_string, ".*");
- leaf_class[0] = '/';
- }
- if(ARG_RPMFORMAT) {
- strcat(out_string, ")");
- }
-
- free(ClassName_Break_Set);
- return out_string;
-}
-
-
-/* Parse out just the class names from a java type and moves the string
- pointer to the end of the string. */
-
-void
-dumpRefType(char *string)
-{
- /* All class types start with a 'L' and and end with a ';'. We want
- everyting in between. There might be more then one per string
- like (params for a method call) */
-
- string = strchr(string, 'L');
- while (string) {
- string++;
- print_table_add(formatClassName(string, ';', 0));
- string = strchr(string, ';');
- string = strchr(string, 'L');
- }
-
- return ;
-}
-
-
-/* Print out the classes referenced in the symbol table */
-
-void
-dumpRequires(symbolTable_t *symbolTable) {
- int tem;
- int ref = 0;
-
- for(tem=1; tem < symbolTable->poolSize; tem++ ) {
-
- /* dump all the classes in the const table. */
- ref = symbolTable->classRef[tem];
- if(ref) {
- char *string = symbolTable->stringList[ref];
- if( !*string ) {
- die("class num: %d, referenced string num: %d, "
- "which is null.\n",
- tem, ref);
- }
- if ( string[0] == '[' ) {
- /*
- This is an array. We need to ingore
- strings like:
- '[B'
- '[[B'
- '[[I'
-
- This hack leaves blank lines in the output
- when a string not containing a class is
- sent to dumpRefType.
- */
- string = strchr(string, 'L');
- if (string) {
- dumpRefType(string);
- }
- } else {
- print_table_add(formatClassName(string, '\0', 0));
- }
- }
-
- /* dump all the references */
- ref = symbolTable->typeRef[tem];
- if (ref) {
- char *string = symbolTable->stringList[ref];
- if ( !*string ) {
- die("type num: %d, referenced string num: %d, "
- "which is null.\n",
- tem, ref);
- }
- /* this is a java type... parse out the class names */
- dumpRefType(string);
- }
-
- } /*end for*/
-
- return ;
-}
-
-
-/* Read a java class files symbol table into memory.
-*/
-
-
-void genSymbolTable (FILE *fileHandle, symbolTable_t *symbolTable)
-{
- char ignore[10];
- int i=0;
-
-
- /* We are called just after fileHandle saw the magic number, seek a
- few bytes in to find the poolsize */
-
- my_fread(&ignore, 4, 1, fileHandle);
-
- my_fread(&(symbolTable->poolSize), 2, 1, fileHandle);
- symbolTable->poolSize=ntohs(symbolTable->poolSize);
-
- /* new the tables */
-
- symbolTable->stringList = (char**) calloc(symbolTable->poolSize,
- sizeof(char*));
- if(!symbolTable->stringList){
- outofmemory();
- }
-
- symbolTable->classRef = (short*) calloc(symbolTable->poolSize,
- sizeof(short*));
- if(!symbolTable->classRef){
- outofmemory();
- }
-
- symbolTable->typeRef = (short*) calloc(symbolTable->poolSize,
- sizeof(short*));
- if(!symbolTable->typeRef){
- outofmemory();
- }
-
- /* zero 'em all out. */
- for(i=0; i < symbolTable->poolSize; i++) {
- symbolTable->stringList[i] = NULL;
- symbolTable->classRef[i] = 0;
- symbolTable->typeRef[i] = 0;
- }
-
-
- /* for the number of entries
- (it starts at 1)
- */
-
- for(i=1; i < symbolTable->poolSize; i++) {
- unsigned short type = 0;
- unsigned short value = 0;
- unsigned char tag = 0;
-
- /* read the type of this entry */
-
- my_fread(&tag, 1, 1, fileHandle);
- switch(tag) {
- case 1: /* master string pool. */
- {
- /* record all these strings */
- char *someString;
- unsigned short length = 0;
-
- /* I am not sure if these strings must be null
- terminated. I termiante them to be safe. */
-
- my_fread(&length, 2, 1, fileHandle);
- length=ntohs(length);
-
- someString = (char*) malloc(length+1);
- if(!someString){
- outofmemory();
- }
- my_fread(someString, length, 1, fileHandle);
- someString[length]=0;
- symbolTable->stringList[i] = someString;
-
- if (ARG_KEYWORDS) {
- char *ptr=0;
-
- /* Each keyword can appear multiple times. Don't
- bother with datastructures to store these strings,
- if we need to print it print it now. */
-
- /* it would be better if instead of printing the
- strings "raw" I turn the space separated list
- into a "\n" separated list*/
-
- if (ARG_REQUIRES) {
- ptr = is_lower_equal(someString, "rpm_requires: ");
- if(ptr){
- print_list(ptr);
- }
- }
- if (ARG_PROVIDES) {
- ptr = is_lower_equal(someString, "rpm_provides: ");
- if(ptr){
- print_list(ptr);
- }
- }
- /* I wish there was a good way to handle this
- ptr = is_lower_equal(someString, "rpm_conflicts: ");
- */
- ptr = is_lower_equal(someString, "$revision: ");
- if(ptr){
- KEYWORD_REVISION=ptr;
- /* terminate the string before " $" */
- ptr = strchr(KEYWORD_REVISION, ' ');
- if (ptr) {
- *ptr = 0;
- }
- }
- ptr = is_lower_equal(someString, "rpm_version: ");
- if(ptr){
- KEYWORD_VERSION=ptr;
- /* terminate the string at first whitespace */
- ptr = strchr(KEYWORD_VERSION, ' ');
- if (ptr) {
- *ptr = 0;
- }
- }
- ptr = is_lower_equal(someString, "rpm_epoch: ");
- if(ptr){
- KEYWORD_EPOCH=ptr;
- /* terminate the string at first whitespace */
- ptr = strchr(KEYWORD_EPOCH, ' ');
- if (ptr) {
- *ptr = 0;
- }
- }
- }
- break;
- }
- case 2: /* unknow type!! */
- die("Unknown type in constant table. "
- "Entry: %d. \n", i);
- break;
- case 3: /* int */
- my_fread(&ignore, 4, 1, fileHandle);
- break;
- case 4: /* float */
- my_fread(&ignore, 4, 1, fileHandle);
- break;
- case 5: /* long (counts as 2) */
- my_fread(&ignore, 8, 1, fileHandle);
- i++;
- break;
- case 6: /* double (counts as 2) */
- my_fread(&ignore, 8, 1, fileHandle);
- i++;
- break;
- case 7: /* Class */
- my_fread(&value, 2, 1, fileHandle);
- symbolTable->classRef[i]=ntohs(value);
- /* record which const it's referencing */
- check_range(i, symbolTable->classRef[i], symbolTable->poolSize);
- break;
- case 8: /* String */
- my_fread(&ignore, 2, 1, fileHandle);
- break;
- case 9: /* field reference */
- my_fread(&ignore, 4, 1, fileHandle);
- break;
- case 10: /* method reference */
- my_fread(&ignore, 4, 1, fileHandle);
- break;
- case 11: /* interface method reference */
- my_fread(&ignore, 4, 1, fileHandle);
- break;
- case 12: /* constant name/type */
- my_fread(&ignore, 2, 1, fileHandle);
- my_fread(&type, 2, 1, fileHandle);
- symbolTable->typeRef[i]=ntohs(type);
- /* record the name, and the type it's referencing. */
- check_range(i, symbolTable->typeRef[i], symbolTable->poolSize);
- break;
- default:
- die("Unknown tag type: %d.\n",
- "Entry: %d. \n", tag, i);
- break;
- }
- }
-
- return ;
-}
-
-
-/* Find the proper name of the current Java Class file and return a
- formatted of the name.
-*/
-
-char*
-findClassName (FILE *fileHandle, symbolTable_t *symbolTable) {
- char ignore[10];
- unsigned short type = 0;
- unsigned short jclass = 0;
- char *className;
-
- /* seek a little past the end of the table */
-
- my_fread(&ignore, 2, 1, fileHandle);
-
- /* read the name of this classfile */
-
- my_fread(&type, 2, 1, fileHandle);
- type=ntohs(type);
- jclass = symbolTable->classRef[type];
- if( !jclass ||
- !symbolTable->stringList[jclass] ) {
- die("Couln't find class: %d, provided by file.\n", jclass);
- }
-
- className=symbolTable->stringList[jclass];
-
- return className;
-
-}
-
-
-/* Print the name of the class that we have found and whos symbol
- table is loaded into memory.
-
- The name may need to have the version number printed after it, if
- there are keywords in the symbol table.
-
- Additionally the class name may need to be printed twice, once with
- the regular name of the class and once with the leaf class replaced
- with a star.
-
-*/
-
-void
-dumpProvides(char *className) {
- char *out_string;
-#ifdef UNUSED
- char *formattedClassName;
- char *newline;
-#endif
-
- /* Provide the star version of this class for jhtml
- dependencies. This option is deprecated since jhtml is
- deprecated. */
-
- if (ARG_STARPROV) {
- print_table_add(formatClassName(className, '\0', 1));
- }
-
- /* If we have information about the version number of this class
- then add it to the formatted name and print this as well. */
-
- out_string = formatClassName(className, '\0', 0);
-
- {
- int len = 10;
-
- if (out_string) {
- len += strlen(out_string);
- }
- if (KEYWORD_EPOCH) {
- len += strlen(KEYWORD_EPOCH);
- }
- if (KEYWORD_VERSION) {
- len += strlen(KEYWORD_VERSION);
- }
- if (KEYWORD_REVISION) {
- len += strlen(KEYWORD_REVISION);
- }
-
- out_string = realloc(out_string, len );
- if (!out_string){
- outofmemory();
- }
-
- }
-
- if( KEYWORD_VERSION || KEYWORD_REVISION ){
- /* It is easier to remove the extra new line here in one place
- then to try and add a newline every where that formatClassName
- is called */
- char *newline;
-
- /* I am not using rpm 3.0 yet so I need both the dependencies with
- and without the version numbers, when I upgrade I will remove
- this block (with copy_string) and change the "=" to " = " ten
- lines down.*/
- {
- char *copy_string;
- copy_string = (char*) malloc(strlen(out_string)+1);
- if (!copy_string){
- outofmemory();
- }
- copy_string = strcpy(copy_string, out_string);
- print_table_add(copy_string);
- }
-
- newline = strrchr(out_string, '\n');
- if (newline) {
- newline[0] = '\0';
- }
- strcat(out_string, " = ");
- if(KEYWORD_EPOCH){
- strcat(out_string, KEYWORD_EPOCH);
- strcat(out_string, ":");
- }
- if(KEYWORD_VERSION){
- strcat(out_string, KEYWORD_VERSION);
- } else {
- strcat(out_string, KEYWORD_REVISION);
- }
- strcat(out_string, "\n");
- }
-
- print_table_add(out_string);
- out_string=NULL;
-
- return ;
-}
-
-
-
-
-
-void freeSymbolTable (symbolTable_t *symbolTable)
-{
- int i=0;
-
- for(i=1; i < symbolTable->poolSize; i++) {
- if( symbolTable->stringList[i] ) {
- free(symbolTable->stringList[i]);
- symbolTable->stringList[i] = 0;
- }
- }
-
- free(symbolTable->stringList);
- symbolTable->stringList=0;
-
- free(symbolTable->classRef);
- symbolTable->classRef=0;
-
- free(symbolTable->typeRef);
- symbolTable->typeRef=0;
-
- return ;
-}
-
-
-/* Process each file.
- This procedure must be called directly after finding
- the magic number.
-*/
-
-void processJavaFile (FILE *fileHandle) {
- symbolTable_t symbolTable= {0};
- char *format_class_name;
-
- genSymbolTable(fileHandle, &symbolTable);
- CLASS_NAME=findClassName(fileHandle, &symbolTable);
-
- if(ARG_DEPSFORMAT) {
- const char *prefix_seperator = ": ";
-
- format_class_name = formatClassName(CLASS_NAME, '\0', 0);
-
- OUTPUT_PREFIX = (char*) malloc(strlen(format_class_name)+
- strlen(prefix_seperator)+1);
- if (!OUTPUT_PREFIX){
- outofmemory();
- }
- OUTPUT_PREFIX = strcpy(OUTPUT_PREFIX, format_class_name);
- strcat(OUTPUT_PREFIX, prefix_seperator);
- }
-
- if(ARG_PROVIDES) {
- dumpProvides(CLASS_NAME);
- }
- if(ARG_REQUIRES) {
- dumpRequires(&symbolTable);
- }
-
- free(OUTPUT_PREFIX);
- OUTPUT_PREFIX = 0;
- freeSymbolTable(&symbolTable);
-
- return ;
-
-}
-
-
-int
-main(int argc, char *argv[])
-{
- FILE *fileHandle;
- int i = 0;
- int rc = 0;
- int foundMagic=0;
-
- PROGRAM_NAME=argv[0];
-
- if(argv[1] == NULL) {
- usage();
- }
-
- /* parse arguments which are not filenames*/
-
- for (i = 1; argv[i] != NULL; i++) {
-
- if (0) {
- /*
- First entry a dummy to get the
- other entries to align correctly
- */
- ;
- } else if ( !strcmp("-p",argv[i]) || !strcmp("--provides",argv[i]) ) {
- ARG_PROVIDES = 1;
- } else if ( !strcmp("-r",argv[i]) || !strcmp("--requires",argv[i]) ) {
- ARG_REQUIRES = 1;
- } else if ( !strcmp("-h",argv[i]) || !strcmp("--help",argv[i]) ||
- !strcmp("-?",argv[i]) ) {
-
- usage();
- } else if ( !strcmp("-F",argv[i]) || !strcmp("--rpmformat",argv[i]) ) {
- ARG_RPMFORMAT=1;
- } else if ( !strcmp("-d",argv[i]) || !strcmp("--depsformat",argv[i]) ) {
- ARG_DEPSFORMAT=1;
- } else if ( !strcmp("-k",argv[i]) || !strcmp("--keywords",argv[i]) ) {
- ARG_KEYWORDS=1;
- } else if ( !strcmp("-s",argv[i]) || !strcmp("--starprov",argv[i]) ) {
- ARG_STARPROV=1;
- } else if ( !strcmp("--",argv[i]) ) {
- i++;
- break;
- } else {
- /* we do not recognize the argument, must be a filename*/
- break;
- }
- } /*end for arguments which are not filenames*/
-
- /* check arguments for consistancy */
-
- if ( !ARG_PROVIDES && !ARG_REQUIRES ) {
- die ("Must specify either --provides or --requires.\n");
- }
-
- if ( ARG_PROVIDES && ARG_REQUIRES ) {
- die ("Can not specify both --provides and --requires.\n");
- }
-
- if ( ARG_REQUIRES && ARG_STARPROV) {
- die ("Can not specify both --requires and --starpov.\n");
- }
-
- if(argv[i] == NULL) {
- die ("Must specify Java class files.\n");
- }
-
- /* parse arguments which are filenames. */
-
- for ( /*null initializer*/; argv[i] != NULL; i++) {
-
- /*open the correct file and process it*/
-
- if ( !strcmp("-", argv[i]) ) {
- /* use stdin, might be a jar file */
- fileHandle = stdin;
- FILE_NAME = "<stdin>";
-
- foundMagic = findJavaMagic(fileHandle);
- while (foundMagic) {
- processJavaFile(fileHandle);
- foundMagic = findJavaMagic(fileHandle);
- }
- } else {
- /* Open a disk file*/
- fileHandle = fopen(argv[i], "r");
- if( fileHandle == 0 ) {
- die ("Could not open file: %s.\n", argv[i]);
- }
- fileHandle = fileHandle;
- FILE_NAME = argv[i];
-
- foundMagic = findJavaMagic(fileHandle);
- if (foundMagic) {
- processJavaFile(fileHandle);
- }
- }
-
- rc = fclose(fileHandle);
- if( rc ) {
- die ("Could not close file: %s.\n", FILE_NAME);
- }
- CLASS_NAME=0;
- } /*end parsing arguments which are filenames*/
-
- print_table_flush();
- return 0;
-}