00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 #include "system.h"
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 #include <stdarg.h>
00068 #include "debug.h"
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 typedef struct {
00077   short poolSize;
00078   char **stringList;
00079   short *classRef;
00080   short *typeRef;
00081 } symbolTable_t;
00082 
00083 
00084 
00085 
00086 
00087 char *PROGRAM_NAME=0;
00088 
00089 
00090 char *FILE_NAME=0;
00091 
00092 
00093 char *CLASS_NAME=0;
00094 
00095 
00096 
00097 char *OUTPUT_PREFIX=0;
00098 
00099 
00100 int ARG_PROVIDES=0;
00101 int ARG_REQUIRES=0;
00102 int ARG_RPMFORMAT=0;
00103 int ARG_DEPSFORMAT=0;
00104 int ARG_KEYWORDS=0;
00105 int ARG_STARPROV=0;
00106 
00107 
00108 char *KEYWORD_VERSION=0;
00109 char *KEYWORD_REVISION=0;
00110 char *KEYWORD_EPOCH=0;
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 #define MAX_PRINT_TABLE 10000
00135 char *PRINT_TABLE[MAX_PRINT_TABLE];
00136 int SIZE_PRINT_TABLE;
00137 
00138 
00139 
00140 void usage (void);
00141 void outofmemory(void);
00142 void die(char *format, ...);
00143 size_t my_fread(void *ptr, size_t size, size_t nitems, FILE *stream);
00144 void check_range(short entryNum, short value, short poolSize);
00145 char *is_lower_equal (char *string, char *pattern);
00146 int findJavaMagic (FILE *fileHandle);
00147 int my_strcmp (const void *a, const void *b);
00148 void print_table_flush(void);
00149 void print_table_add(char *str);
00150 char *formatClassName(char *pSomeString, char terminator, char print_star);
00151 void dumpRefType(char *pSomeString);
00152 void genSymbolTable (FILE *fileHandle, symbolTable_t *symbolTable);
00153 void freeSymbolTable (symbolTable_t *symbolTable);
00154 char *findClassName (FILE *fileHandle, symbolTable_t *symbolTable);
00155 void dumpProvides(char *className);
00156 void dumpRequires(symbolTable_t *symbolTable);
00157 void processJavaFile (FILE *fileHandle);
00158 
00159 
00160 
00161 void
00162 usage (void)
00163 {
00164   printf("NAME:\n\tjavadeps - Examine Java class files and\n"
00165          "\t\t\treturn information about their dependencies.\n\n");
00166   printf("USAGE:\n");
00167   printf("\t javadeps { --provides | --requires } \n"
00168          "\t\t   [--rpmformat] [--depsformat] [--keywords] \n"
00169          "\t\t     [--] classfile-name ... \n\n"
00170          "\t javadeps [--help]\n\n");
00171   printf("\n\n");
00172   printf("DESCRIPTION:\n\n");
00173   printf("List the dependencies or the fully qualified class names, of the \n"
00174          "classfiles listed on the command line. \n\n");
00175   printf("OPTIONS:\n\n");
00176   printf("--requires   For each class files listed in the arguments,\n"
00177          " -r          print the list of class files that would be\n"
00178          "             required to run these java programs.  This does not \n"
00179          "             include anyting instantiated by reflection.\n\n");
00180   printf("--provides   For each class files listed in the arguments, \n"
00181          " -p          Print the fully qualified java classes,\n"
00182          "             that they provide.\n\n");
00183   printf("--rpmformat  Format the output to match that used by RPM's \n"
00184          " -F          (Red Hat Package Manager) dependency analysis  \n"
00185          "             database. The default is not --rpmformat.\n\n");
00186   printf("--depsformat print the name of the class which  \n"
00187          " -d          This is mostly used in conjunctions with --requires \n"
00188          "             to list the class file dependencies in a format "
00189          "             similar to traditional Makefile dependencies. The "
00190          "             default is not --depsformat.\n\n");
00191   printf("--keywords   Make use of any keywords embeded in the classfile.\n"
00192          " -k          The default is not --keyword.\n\n");
00193   printf("--starprov   Add the star notation provides to the provides list.\n"
00194          " -s          The default is not --starprov.  This is only for use\n"
00195          "             with (Sun) jhtml dependencies, and since jhtml is \n"
00196          "             deprecated so is this option.\n\n");
00197   printf("--help       Display this page and exit.\n\n");
00198   printf("--           This stops the processing of arguments, making it \n"
00199          "             easier for users to have filenames like '--keywords',\n"
00200          "             without the command line parser getting confused.\n\n");
00201   printf("\n\n");
00202   printf("If any of the class file names in the argument list is '-' then\n"
00203          "<stdin> will be read instead of reading from a file.  The\n"
00204          "contents of <stdin> should be the contents of a class file and \n"
00205          "not a list of class files to read.  It is assumed that when run \n"
00206          "with '-', this program is in a pipeline preceeded by the \n"
00207          "command 'unzip -p filename.jar' so that <stdin> may contain\n"
00208          "the contents of several classfiles concatenated together.\n");
00209   printf("\n\n");
00210   printf("If --keywords is specified then the following strings are \n"
00211          "searched for (case insensitive) in the class file string table\n"
00212          "and, if a string is found with a prefix matching the keyword then \n"
00213          "the dependencies are changed accordingly.  There may be multiple \n"
00214          "string tables entries prefixed with RPM_Provides and RPM_Requires. \n"
00215          "This would indicate that the dependency is the union\n"
00216          "of all entries.\n"
00217          "\n\n"
00218          "Keyword List:\n\n"
00219          "'$Revision: '     This RCS/CVS compatible keyword is assumed to \n"
00220          "                  contain the version number of the class file \n"
00221          "                  it is found in.  Care should be taken with this\n" 
00222          "                  option as RPM's notion of which version is later\n"
00223          "                  may not corrispond with your own, especially\n"
00224          "                  if you use branches. This keyword\n"
00225          "                  only effects the output of --provides and only\n"
00226          "                  when RPM_Version is not defined.\n\n"
00227          "'RPM_Version: '   This is an alternative method of specifing the\n"
00228          "                  version number of the class.  It will override\n"
00229          "                  $Revision if set.   This keyword only effects\n"
00230          "                  the output of --provides \n\n"
00231          "'RPM_Epoch: '     This string contains the epoch to use with the \n"
00232          "                  version number stored in Revision.  If not \n"
00233          "                  specified, the epoch is assumed to be zero.\n"
00234          "                  This keyword only effects the output of\n "
00235          "                  --provides and only when $Revision number is\n"
00236          "                  used.\n\n"
00237          "'RPM_Provides: '  This string lists additional capabilites\n"
00238          "                  provided by the java class.  The string should\n"
00239          "                  be  a white space ([\\t\\v\\n\\r\\f\\ ])\n"
00240          "                  separated list of dependency strings.  Each\n"
00241          "                  dependency string must be of the same format as\n"
00242          "                  would be valid in the Requires or Provides line\n"
00243          "                  of the specfile. This keyword only effects the\n"
00244          "                  output of --provides.\n\n"
00245          "'RPM_Requires: '  This string lists additional requirements of\n"
00246          "                  the java class.  The string should be a white \n"
00247          "                  space ([\\t   \v\\n\\r\\f\\ ]) separated list of \n"
00248          "                  dependency strings.  Each dependency string must\n"
00249          "                  be of the same format as would be valid in the \n"
00250          "                  Requires or Provides line of the specfile.  This\n"
00251          "                  keyword only effects the output of --requires.\n "
00252          "                  \n\n"
00253          "Note that there is no means of setting the release number.  This\n"
00254          "is necessary because release numbers are incremented when the\n"
00255          "source does not change but the package needs to be rebuilt.  So\n"
00256          "relase numbers can not be stored in the source.  The release is\n"
00257          "assumed to be zero. \n\n"
00258          "");
00259   printf("EXAMPLES (Java Keywords): \n\n"
00260          "\t public static final String REVISION = \"$Revision: 2.12 $\";\n"
00261          "\t public static final String EPOCH = \"4\";\n"
00262          "\t public static final String REQUIRES = \"RPM_Requires: "
00263          "java(gnu.regexp.RE) java(com.ibm.site.util.Options)>=1.5\";\n"
00264          "");
00265   printf("\n\n");
00266   printf("EXAMPLES (Arguments): \n\n"
00267          "\tjavadeps --requires -- filename.class\n\n"
00268          "\tjavadeps --provides -- filename.class\n\n"
00269          "\tjavadeps --help\n\n"
00270          "\n"
00271          "\tjavadeps --requires --rpmformat --keywords -- filename.class\n\n"
00272          "\tjavadeps --requires --depsformat -- filename.class\n\n"
00273          "\tjavadeps --requires -- filename1.class filename2.class\n\n"
00274          "\tcat filename2.class | javadeps --requires -- filename1.class -\n\n"
00275          "\tunzip -p filename.jar | javadeps --requires -- - \n\n"
00276          "");
00277   printf("This program is distributed with RPM the Redhat Package \n"
00278          "Managment system.  Further information about RPM can be found at \n"
00279          "\thttp://www.rpm.org/\n\n");
00280   printf("\n\n");
00281   exit(-1);
00282 }
00283 
00284 
00285 void outofmemory(void) {
00286 
00287   
00288 
00289 
00290   fprintf(stderr, "Could not allocate memory\n");
00291   exit(-1);
00292 }
00293 
00294 
00295 void die(char *format, ...) {
00296   
00297 
00298 
00299 
00300   char  *newformat = NULL, *newmsg = NULL;
00301   va_list ap;
00302 
00303   if ( 
00304       !(newformat = (char*) malloc(1024)) || 
00305       !(newmsg = (char*) malloc(1024)) 
00306       )
00307     outofmemory();
00308 
00309   
00310 
00311 
00312 
00313 
00314   
00315 
00316 
00317 
00318 
00319   if ( (!FILE_NAME) ) {
00320 
00321     sprintf (newformat, "\n%s: %s",
00322              PROGRAM_NAME, format);
00323 
00324   } else if ( (FILE_NAME) && (!CLASS_NAME) ) {
00325     
00326     sprintf (newformat, "\n%s: Java classfile: %s, %s",
00327              PROGRAM_NAME, FILE_NAME, format);
00328     
00329   } else if (CLASS_NAME) {
00330     sprintf (newformat, "\n%s: Java classfile: %s, classname: %s, %s",
00331              PROGRAM_NAME, FILE_NAME, CLASS_NAME, format);
00332   }
00333     
00334   va_start(ap, format);
00335   vsprintf (newmsg, newformat, ap);  
00336   va_end(ap);
00337   
00338   
00339 
00340 
00341 
00342   fprintf(stderr, newmsg);
00343   
00344   free(newformat);
00345   free(newmsg);
00346   
00347   exit(-1);
00348 }
00349 
00350 
00351 
00352 
00353 
00354 size_t my_fread(void *ptr, size_t size, size_t nitems, FILE *stream) {
00355   size_t rc=0;
00356   
00357   int eof=0;
00358   int error=0;
00359 
00360 
00361   rc = fread(ptr, size, nitems, stream);
00362   if ( (size!=0) && (rc == 0) ) {
00363     eof = feof(stream);
00364     error = ferror(stream);
00365     die("Error reading from file, or unexpected EOF\n");
00366   }
00367   return rc;
00368 }
00369 
00370 
00371 void check_range(short entryNum, short value, short poolSize) {
00372 
00373   if (value > poolSize) {
00374     die("Symbol Table Entry Number: %d, Value: %d, "
00375         "is out of range of the constant pool. Pool Size: %d\n",
00376         entryNum, value, poolSize);
00377   }
00378   return ;
00379 }
00380  
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 char 
00392 *is_lower_equal (char *string, char *pattern) 
00393 {
00394   
00395   while ( (tolower(*string) == *pattern) && 
00396           *string && *pattern )  {
00397     string++; 
00398     pattern++;
00399   }
00400 
00401   if ( *pattern == 0 ) {
00402     return string;
00403   } 
00404 
00405   return NULL;
00406 }
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 #define mod4(num) ( (num) & 3 )
00419 
00420 
00421 int findJavaMagic (FILE *fileHandle)
00422 {
00423   int offset=0;
00424   int foundMagic = 0;
00425   size_t rc;
00426 
00427   
00428   unsigned char magicInt[4] = {0xCA, 0xFE, 0xBA, 0xBE};
00429   
00430 
00431   
00432   unsigned char buffer[4] = {0};
00433 
00434   foundMagic = 0;
00435   while( !foundMagic ) {
00436 
00437       rc = fread(&buffer[offset], 1, 1, fileHandle);
00438       if ( !rc ) {
00439 
00440         
00441 
00442 
00443         if ( feof(fileHandle) ) {
00444           return 0;
00445         }
00446         
00447         if ( ferror(fileHandle) ) {
00448           die ("Error reading character from file.\n");
00449         };
00450 
00451       }
00452       
00453       
00454 
00455 
00456       foundMagic = (
00457                     (magicInt[0] == buffer[mod4(offset+1)]) && 
00458                     (magicInt[1] == buffer[mod4(offset+2)]) && 
00459                     (magicInt[2] == buffer[mod4(offset+3)]) && 
00460                     (magicInt[3] == buffer[mod4(offset+0)]) && 
00461                     1
00462                     );  
00463 
00464       offset = mod4(offset+1);
00465       
00466     } 
00467 
00468   return foundMagic;
00469 }
00470 
00471 #undef mod4
00472 
00473 
00474 int
00475 my_strcmp (const void *a, const void *b) {
00476 char **a1; char **b1;
00477 int ret;
00478 
00479 a1 = (char **)a;
00480 b1 = (char **)b;
00481 ret = strcmp(*a1,*b1);
00482   return ret;
00483 }
00484 
00485 
00486 
00487 void 
00488 print_table_flush(void) {
00489   int i;
00490   char *last_string;
00491 
00492   if (!SIZE_PRINT_TABLE) {
00493     return ;
00494   }
00495 
00496   
00497 
00498 
00499 
00500   qsort( (void *) PRINT_TABLE, (size_t) SIZE_PRINT_TABLE, 
00501          sizeof(char *), &my_strcmp);
00502 
00503   printf("%s\n",PRINT_TABLE[0]);
00504   last_string = PRINT_TABLE[0];
00505   PRINT_TABLE[0] = NULL;
00506   
00507   for (i = 1; i < SIZE_PRINT_TABLE; i++) {
00508     if ( strcmp(last_string, PRINT_TABLE[i]) ){
00509       printf("%s\n",PRINT_TABLE[i]);
00510       free(last_string);
00511       last_string = PRINT_TABLE[i];
00512     } else {
00513       free(PRINT_TABLE[i]);
00514     }
00515     PRINT_TABLE[i] = NULL;
00516   }
00517   
00518   free(last_string);
00519   SIZE_PRINT_TABLE = 0;
00520   return ; 
00521 }
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 void 
00531 print_table_add(char *str) {
00532 
00533   if (SIZE_PRINT_TABLE == MAX_PRINT_TABLE) {
00534     print_table_flush();
00535   }
00536   
00537   if (OUTPUT_PREFIX) {
00538     char *new_str;
00539 
00540     new_str= (char*) malloc(strlen(OUTPUT_PREFIX)+strlen(str)+1);
00541     if (!new_str){
00542       outofmemory();
00543     }
00544 
00545     new_str[0]='\0';
00546     strcat(new_str,OUTPUT_PREFIX);
00547     strcat(new_str,str);
00548     free(str);
00549     str=new_str;
00550   }
00551 
00552   PRINT_TABLE[SIZE_PRINT_TABLE] = str;
00553   SIZE_PRINT_TABLE++;
00554   return ;
00555 }
00556 
00557 
00558 static void 
00559 print_list(char *in_string) {
00560 
00561   
00562 
00563 
00564 
00565   if (in_string) {
00566     printf("%s\n", in_string);
00567   }
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575  
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612  return ;
00613 }
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 char
00631 *formatClassName(char *in_string, char terminator, 
00632                  char print_star)
00633 { 
00634   char *leaf_class=0, *out_string=0;
00635   char *ClassName_Break_Set=0;
00636 
00637 
00638   out_string = (char*) malloc(strlen(in_string) + 10);
00639   if ( !out_string ) {
00640     outofmemory();
00641   }
00642   out_string[0]= '\0';
00643   
00644   
00645 
00646   
00647   ClassName_Break_Set = (char*) malloc(3);
00648   if ( !ClassName_Break_Set ) {
00649     outofmemory();
00650   }
00651   ClassName_Break_Set[0] = '/';
00652   
00653   ClassName_Break_Set[1] = terminator;
00654   ClassName_Break_Set[2] = '\0';
00655   
00656   if(ARG_RPMFORMAT) {
00657     strcat(out_string, "java(");
00658   }
00659   if (print_star) {
00660     
00661 
00662     leaf_class = strrchr(in_string, '/');
00663     if (leaf_class) {
00664       leaf_class[0] = terminator;
00665     }
00666   }
00667   
00668   while (*in_string != terminator) {
00669     char *newEnd=0;
00670     int copy_len;
00671 
00672     
00673 
00674     if (in_string[0] == '\0' ) {
00675       die("Classname does not terminate with: '%c', '%s'\n", 
00676           terminator, in_string);
00677     } else {
00678       if (in_string[0] == '/' ) {
00679         
00680         strcat(out_string, ".");
00681         in_string++;
00682       }
00683     }
00684 
00685     newEnd = strpbrk(in_string, ClassName_Break_Set);
00686 
00687     if  (newEnd) {
00688       copy_len = newEnd-in_string;
00689     } else {
00690       if (terminator == '\0') {
00691         copy_len = strlen(in_string);
00692       } else {
00693         copy_len = 0;
00694       }
00695     }
00696     
00697     
00698     if (copy_len) {
00699       strncat(out_string, in_string, copy_len);
00700       in_string+=copy_len;
00701     }
00702 
00703   } 
00704   
00705   if (leaf_class) {
00706     
00707     strcat(out_string, ".*"); 
00708     leaf_class[0] = '/';
00709   }
00710   if(ARG_RPMFORMAT) {
00711     strcat(out_string, ")");
00712   }
00713 
00714   free(ClassName_Break_Set);
00715   return out_string;
00716 }
00717 
00718 
00719 
00720 
00721 
00722 void
00723 dumpRefType(char *string)
00724 {
00725   
00726 
00727 
00728 
00729   string = strchr(string, 'L');
00730   while (string) {
00731     string++;
00732     print_table_add(formatClassName(string, ';', 0));
00733     string = strchr(string, ';');
00734     string = strchr(string, 'L');
00735   }
00736   
00737   return ;
00738 }
00739 
00740 
00741 
00742 
00743 void
00744 dumpRequires(symbolTable_t *symbolTable) {
00745   int tem;
00746   int ref = 0;
00747 
00748   for(tem=1; tem < symbolTable->poolSize; tem++ ) {
00749 
00750     
00751     ref = symbolTable->classRef[tem];
00752     if(ref) {
00753       char *string = symbolTable->stringList[ref];
00754       if( !*string ) {
00755         die("class num: %d, referenced string num: %d, "
00756             "which is null.\n",
00757             tem, ref);
00758       }
00759       if ( string[0] == '[' ) {
00760         
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771         string = strchr(string, 'L');
00772         if (string) {
00773           dumpRefType(string);
00774         }
00775       } else {
00776         print_table_add(formatClassName(string, '\0', 0));
00777       }
00778     }
00779     
00780     
00781     ref = symbolTable->typeRef[tem];
00782     if (ref) {
00783       char *string = symbolTable->stringList[ref];
00784       if ( !*string ) {
00785         die("type num: %d, referenced string num: %d, "
00786             "which is null.\n",
00787             tem, ref);
00788       }
00789       
00790       dumpRefType(string);
00791     } 
00792     
00793   } 
00794   
00795   return ;
00796 }
00797 
00798 
00799 
00800 
00801 
00802 
00803 void genSymbolTable (FILE *fileHandle, symbolTable_t *symbolTable)
00804 {
00805   char ignore[10];
00806   int i=0;
00807   
00808 
00809   
00810 
00811 
00812   my_fread(&ignore, 4, 1, fileHandle);
00813 
00814   my_fread(&(symbolTable->poolSize), 2, 1, fileHandle);
00815   symbolTable->poolSize=ntohs(symbolTable->poolSize);
00816 
00817   
00818 
00819   symbolTable->stringList = (char**) calloc(symbolTable->poolSize, 
00820                                             sizeof(char*));
00821   if(!symbolTable->stringList){
00822     outofmemory();
00823   }
00824   
00825   symbolTable->classRef = (short*) calloc(symbolTable->poolSize,
00826                                           sizeof(short*));
00827   if(!symbolTable->classRef){
00828     outofmemory();
00829   }
00830   
00831   symbolTable->typeRef = (short*) calloc(symbolTable->poolSize,
00832                                          sizeof(short*));
00833   if(!symbolTable->typeRef){
00834     outofmemory();
00835   }
00836   
00837   
00838   for(i=0; i < symbolTable->poolSize; i++) {
00839     symbolTable->stringList[i] = NULL;
00840     symbolTable->classRef[i] = 0;
00841     symbolTable->typeRef[i] = 0;
00842   }
00843   
00844   
00845   
00846 
00847 
00848 
00849   for(i=1; i < symbolTable->poolSize; i++) {
00850     unsigned short type = 0;
00851     unsigned short value = 0;
00852     unsigned char tag = 0;
00853 
00854       
00855 
00856       my_fread(&tag, 1, 1, fileHandle);
00857       switch(tag) {
00858         case 1: 
00859           {
00860             
00861                 char *someString;
00862                 unsigned short length = 0;
00863 
00864                 
00865 
00866 
00867                 my_fread(&length, 2, 1, fileHandle);
00868                 length=ntohs(length);
00869 
00870                 someString = (char*) malloc(length+1);
00871                 if(!someString){
00872                   outofmemory();
00873                 }
00874                 my_fread(someString, length, 1, fileHandle);
00875                 someString[length]=0;
00876                 symbolTable->stringList[i] = someString;
00877                 
00878                 if (ARG_KEYWORDS) {
00879                   char *ptr=0;
00880 
00881                   
00882 
00883 
00884 
00885                   
00886 
00887 
00888                   
00889                   if (ARG_REQUIRES) {
00890                     ptr = is_lower_equal(someString, "rpm_requires: ");
00891                     if(ptr){
00892                       print_list(ptr);
00893                     }
00894                   }
00895                   if (ARG_PROVIDES) {
00896                     ptr = is_lower_equal(someString, "rpm_provides: ");
00897                     if(ptr){
00898                       print_list(ptr);
00899                     }
00900                   }
00901                   
00902 
00903 
00904                   ptr = is_lower_equal(someString, "$revision: ");
00905                   if(ptr){
00906                     KEYWORD_REVISION=ptr;
00907                     
00908                     ptr = strchr(KEYWORD_REVISION, ' ');
00909                     if (ptr) {
00910                       *ptr = 0;
00911                     }
00912                   }
00913                   ptr = is_lower_equal(someString, "rpm_version: ");
00914                   if(ptr){
00915                     KEYWORD_VERSION=ptr;
00916                     
00917                     ptr = strchr(KEYWORD_VERSION, ' ');
00918                     if (ptr) {
00919                       *ptr = 0;
00920                     }
00921                   }
00922                   ptr = is_lower_equal(someString, "rpm_epoch: ");
00923                   if(ptr){
00924                     KEYWORD_EPOCH=ptr;
00925                     
00926                     ptr = strchr(KEYWORD_EPOCH, ' ');
00927                     if (ptr) {
00928                       *ptr = 0;
00929                     }
00930                   }
00931                 }
00932                 break;
00933           }
00934       case 2:   
00935           die("Unknown type in constant table. "
00936               "Entry: %d. \n", i);
00937           break;
00938         case 3: 
00939           my_fread(&ignore, 4, 1, fileHandle);
00940           break;
00941         case 4: 
00942           my_fread(&ignore, 4, 1, fileHandle);
00943           break;
00944         case 5: 
00945           my_fread(&ignore, 8, 1, fileHandle);
00946           i++;
00947           break;
00948         case 6: 
00949           my_fread(&ignore, 8, 1, fileHandle);
00950           i++;
00951           break;
00952         case 7: 
00953           my_fread(&value, 2, 1, fileHandle);
00954           symbolTable->classRef[i]=ntohs(value);
00955           
00956           check_range(i, symbolTable->classRef[i], symbolTable->poolSize);
00957           break;
00958         case 8: 
00959           my_fread(&ignore, 2, 1, fileHandle);
00960           break;
00961         case 9: 
00962           my_fread(&ignore, 4, 1, fileHandle);
00963           break;
00964         case 10: 
00965           my_fread(&ignore, 4, 1, fileHandle);
00966           break;
00967         case 11: 
00968           my_fread(&ignore, 4, 1, fileHandle);
00969           break;
00970         case 12: 
00971           my_fread(&ignore, 2, 1, fileHandle);
00972           my_fread(&type, 2, 1, fileHandle);
00973           symbolTable->typeRef[i]=ntohs(type);
00974           
00975           check_range(i, symbolTable->typeRef[i], symbolTable->poolSize);
00976           break;
00977         default:
00978           die("Unknown tag type: %d.\n",
00979               "Entry: %d. \n", tag, i);
00980           break;
00981       }
00982   }
00983 
00984   return ;  
00985 }
00986  
00987 
00988 
00989 
00990 
00991 
00992 char*
00993 findClassName (FILE *fileHandle, symbolTable_t *symbolTable) {
00994   char ignore[10];
00995   unsigned short type = 0;
00996   unsigned short class = 0;
00997   char *className;
00998 
00999   
01000   
01001   my_fread(&ignore, 2, 1, fileHandle);
01002   
01003   
01004   
01005   my_fread(&type, 2, 1, fileHandle);
01006   type=ntohs(type);
01007   class = symbolTable->classRef[type];
01008   if( !class ||
01009       !symbolTable->stringList[class] ) {
01010       die("Couln't find class: %d, provided by file.\n", class);
01011   }
01012 
01013   className=symbolTable->stringList[class];
01014   
01015   return className;
01016 
01017 }
01018 
01019 
01020 
01021 
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 void
01033 dumpProvides(char *className) {
01034   char *out_string;
01035 #ifdef  UNUSED
01036   char *formattedClassName;
01037   char *newline;
01038 #endif
01039 
01040   
01041 
01042 
01043   
01044   if (ARG_STARPROV) {
01045     print_table_add(formatClassName(className, '\0', 1));
01046   }
01047 
01048   
01049 
01050 
01051   out_string = formatClassName(className, '\0', 0);
01052 
01053   {
01054     int len = 10;
01055 
01056     if (out_string) {
01057       len += strlen(out_string);
01058     }
01059     if (KEYWORD_EPOCH) {
01060       len += strlen(KEYWORD_EPOCH);
01061     }
01062     if (KEYWORD_VERSION) {
01063       len += strlen(KEYWORD_VERSION);
01064     }
01065     if (KEYWORD_REVISION) {
01066       len += strlen(KEYWORD_REVISION);
01067     }
01068     
01069     out_string = realloc(out_string, len );
01070     if (!out_string){
01071       outofmemory();
01072     }
01073   
01074   }
01075 
01076   if( KEYWORD_VERSION || KEYWORD_REVISION ){
01077     
01078 
01079 
01080     char *newline;
01081 
01082     
01083 
01084 
01085 
01086     {
01087       char *copy_string;
01088       copy_string = (char*) malloc(strlen(out_string)+1);
01089       if (!copy_string){
01090         outofmemory();
01091       }
01092       copy_string = strcpy(copy_string, out_string);
01093       print_table_add(copy_string);
01094     }
01095 
01096     newline = strrchr(out_string, '\n');
01097     if (newline) {
01098       newline[0] = '\0';
01099     }
01100     strcat(out_string, " = ");
01101     if(KEYWORD_EPOCH){
01102       strcat(out_string, KEYWORD_EPOCH);
01103       strcat(out_string, ":");
01104     }
01105     if(KEYWORD_VERSION){
01106       strcat(out_string, KEYWORD_VERSION);
01107     } else {
01108       strcat(out_string, KEYWORD_REVISION);
01109     }
01110     strcat(out_string, "\n");
01111   }
01112 
01113   print_table_add(out_string);
01114   out_string=NULL;
01115 
01116   return ;  
01117 }
01118 
01119 
01120 
01121 
01122 
01123 void freeSymbolTable (symbolTable_t *symbolTable)
01124 {  
01125   int i=0;
01126 
01127   for(i=1; i < symbolTable->poolSize; i++) {
01128     if( symbolTable->stringList[i] ) {
01129       free(symbolTable->stringList[i]);
01130       symbolTable->stringList[i] = 0;
01131     }
01132   }
01133   
01134   free(symbolTable->stringList);
01135   symbolTable->stringList=0;
01136   
01137   free(symbolTable->classRef);
01138   symbolTable->classRef=0;
01139   
01140   free(symbolTable->typeRef);
01141   symbolTable->typeRef=0;
01142   
01143   return ;
01144 }
01145 
01146 
01147 
01148 
01149 
01150 
01151 
01152 void processJavaFile (FILE *fileHandle) {
01153   symbolTable_t symbolTable= {0};
01154   char *format_class_name;
01155 
01156   genSymbolTable(fileHandle, &symbolTable);
01157   CLASS_NAME=findClassName(fileHandle, &symbolTable);
01158   
01159   if(ARG_DEPSFORMAT) {
01160     char *prefix_seperator = ": ";
01161 
01162     format_class_name = formatClassName(CLASS_NAME, '\0', 0);
01163 
01164     OUTPUT_PREFIX = (char*) malloc(strlen(format_class_name)+
01165                                    strlen(prefix_seperator)+1);
01166     if (!OUTPUT_PREFIX){
01167       outofmemory();
01168     }
01169     OUTPUT_PREFIX = strcpy(OUTPUT_PREFIX, format_class_name);
01170     strcat(OUTPUT_PREFIX, prefix_seperator);
01171   }
01172 
01173   if(ARG_PROVIDES) {
01174     dumpProvides(CLASS_NAME);
01175   }
01176   if(ARG_REQUIRES) {
01177     dumpRequires(&symbolTable);
01178   }
01179 
01180   free(OUTPUT_PREFIX);
01181   OUTPUT_PREFIX = 0;
01182   freeSymbolTable(&symbolTable);
01183 
01184   return ;
01185 
01186 }
01187 
01188 
01189 int
01190 main(int argc, char **argv)
01191 {
01192   FILE *fileHandle;
01193   int i = 0;
01194   int rc = 0;
01195   int foundMagic=0;
01196 
01197   PROGRAM_NAME=argv[0];
01198   
01199   if(argv[1] == NULL) {
01200     usage();
01201   }
01202   
01203   
01204   
01205   for (i = 1; argv[i] != NULL; i++) {
01206     
01207     if (0) {
01208       
01209 
01210 
01211 
01212       ;
01213     } else if ( !strcmp("-p",argv[i]) || !strcmp("--provides",argv[i]) ) {
01214       ARG_PROVIDES = 1;
01215     } else if ( !strcmp("-r",argv[i]) || !strcmp("--requires",argv[i]) ) {
01216       ARG_REQUIRES = 1;
01217     } else if ( !strcmp("-h",argv[i]) || !strcmp("--help",argv[i]) ||
01218                 !strcmp("-?",argv[i]) ) {
01219                 
01220       usage();
01221     } else if ( !strcmp("-F",argv[i]) || !strcmp("--rpmformat",argv[i]) ) {
01222       ARG_RPMFORMAT=1;
01223     } else if ( !strcmp("-d",argv[i]) || !strcmp("--depsformat",argv[i]) ) {
01224       ARG_DEPSFORMAT=1;
01225     } else if ( !strcmp("-k",argv[i]) || !strcmp("--keywords",argv[i]) ) {
01226       ARG_KEYWORDS=1;
01227     } else if ( !strcmp("-s",argv[i]) || !strcmp("--starprov",argv[i]) ) {
01228       ARG_STARPROV=1;
01229     } else if ( !strcmp("--",argv[i]) ) {
01230       i++;
01231       break;      
01232     } else {
01233       
01234       break;
01235     }
01236   } 
01237   
01238   
01239 
01240   if ( !ARG_PROVIDES && !ARG_REQUIRES ) {
01241     die ("Must specify either --provides or --requires.\n");
01242   }
01243   
01244   if ( ARG_PROVIDES && ARG_REQUIRES ) {
01245     die ("Can not specify both --provides and --requires.\n");
01246   }
01247   
01248   if ( ARG_REQUIRES && ARG_STARPROV) {
01249     die ("Can not specify both --requires and --starpov.\n");
01250   }
01251   
01252   if(argv[i] == NULL) {
01253     die ("Must specify Java class files.\n");
01254   }
01255   
01256   
01257 
01258   for ( ; argv[i] != NULL; i++) {
01259     
01260     
01261     
01262     if ( !strcmp("-", argv[i]) ) {
01263       
01264       fileHandle = stdin;
01265       FILE_NAME = "<stdin>";
01266 
01267       foundMagic = findJavaMagic(fileHandle);      
01268       while (foundMagic) {      
01269         processJavaFile(fileHandle);
01270         foundMagic = findJavaMagic(fileHandle);
01271       } 
01272     } else {
01273       
01274       fileHandle = fopen(argv[i], "r");
01275       if( fileHandle == 0 ) {
01276         die ("Could not open file: %s.\n", argv[i]);
01277       }
01278       fileHandle = fileHandle;
01279       FILE_NAME = argv[i];      
01280 
01281       foundMagic = findJavaMagic(fileHandle);      
01282       if (foundMagic) { 
01283         processJavaFile(fileHandle);
01284       }
01285     }
01286 
01287     rc = fclose(fileHandle);
01288     if( rc ) {
01289       die ("Could not close file: %s.\n", FILE_NAME);
01290     }
01291     CLASS_NAME=0;    
01292   } 
01293   
01294   print_table_flush();
01295   return 0;
01296 }