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 }