home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / kaffe-0.5p4-src.tgz / tar.out / contrib / kaffe / kaffevm / findClass.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  193 lines

  1. /*
  2.  * findClass.c
  3.  * Search the CLASSPATH for the given class name.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  12.  */
  13.  
  14. #define    FDBG(s)
  15. #define ZDBG(s)
  16. #define    PDBG(s)
  17. #define    CDBG(s)
  18.  
  19. #include "config.h"
  20. #include <stdio.h>
  21. #include <assert.h>
  22. #if defined(HAVE_UNISTD_H)
  23. #include <unistd.h>
  24. #endif
  25. #if defined(HAVE_IO_H)
  26. #include <io.h>
  27. #endif
  28. #include <stdlib.h>
  29. #include <fcntl.h>
  30. #include <string.h>
  31. #include <sys/stat.h>
  32. #include "errors.h"
  33. #include "file.h"
  34. #include "exception.h"
  35. #include "zipfile.h"
  36. #include "readClass.h"
  37. #include "paths.h"
  38.  
  39. #if !defined(S_ISDIR)
  40. #define    S_ISDIR(m)    ((m) & S_IFDIR)
  41. #endif
  42. #if !defined(O_BINARY)
  43. #define    O_BINARY    0
  44. #endif
  45. #ifndef SEEK_SET
  46. #define SEEK_SET  0
  47. #define SEEK_CUR  1
  48. #define SEEK_END  2
  49. #endif
  50.  
  51. #define    CLASSPATH    "CLASSPATH"
  52. #define    MAXBUF        256
  53. #define    MAXPATHELEM    16
  54.  
  55. #define    CP_INVALID    0
  56. #define    CP_FILE        1
  57. #define    CP_DIR        2
  58.  
  59. static struct {
  60.     int    type;
  61.     char*    path;
  62.     ZipFile    zipf;
  63. } classpath[MAXPATHELEM+1];
  64.  
  65. char* realClassPath;
  66.  
  67. void initClasspath(void);
  68.  
  69. /*
  70.  * Find the named class in a directory or zip file.
  71.  */
  72. void
  73. findClass(char* cname)
  74. {
  75.     int i;
  76.     char buf[MAXBUF];
  77.     int fp;
  78.     struct stat sbuf;
  79.     classFile hand;
  80.     ZipDirectory *zipd;
  81.     int j;
  82.  
  83.     /* Look for the class */
  84. CDBG(    printf("Scanning for class %s\n", cname);        )
  85.     for (i = 0; classpath[i].path != 0; i++) {
  86.         switch (classpath[i].type) {
  87.         case CP_FILE:
  88. ZDBG(            printf("Opening zip file %s for %s\n", classpath[i].path, cname); )
  89.             if (classpath[i].zipf.central_directory == 0) {
  90.                 classpath[i].zipf.fd = open(classpath[i].path, O_RDONLY|O_BINARY);
  91.                 if (classpath[i].zipf.fd < 0 || read_zip_archive (&classpath[i].zipf) != 0) {
  92.                     continue;
  93.                 }
  94.                 close(classpath[i].zipf.fd);
  95.             }
  96.  
  97.             strcpy(buf, cname);
  98.             strcat(buf, ".class");
  99.             zipd = (ZipDirectory*)classpath[i].zipf.central_directory;
  100.             for (j = 0; j < classpath[i].zipf.count; j++, zipd = ZIPDIR_NEXT(zipd)) {
  101. ZDBG(    printf ("%d: size:%d, name(#%d)%s, offset:%d\n", i, zipd->size,
  102.   zipd->filename_length, ZIPDIR_FILENAME (zipd), zipd->filestart);    )
  103.                 if (buf[0] == ZIPDIR_FILENAME(zipd)[0] && strcmp(buf, ZIPDIR_FILENAME(zipd)) == 0) {
  104. ZDBG(                    printf("FOUND!!\n");        )
  105.                     fp = open(classpath[i].path, O_RDONLY|O_BINARY);
  106.                     lseek(fp, zipd->filestart, SEEK_SET);
  107.                     hand.size = zipd->size;
  108.                     goto found;
  109.                 }
  110.             }
  111.             continue;
  112.  
  113.         case CP_DIR:
  114.             strcpy(buf, classpath[i].path);
  115.             strcat(buf, DIRSEP);
  116.             strcat(buf, cname);
  117.             strcat(buf, ".class");
  118. FDBG(            printf("Opening java file %s for %s\n", buf, cname); )
  119.             fp = open(buf, O_RDONLY|O_BINARY);
  120.             if (fp < 0 || fstat(fp, &sbuf) < 0) {
  121.                 continue;
  122.             }
  123.             hand.size = sbuf.st_size;
  124.  
  125.         found:
  126.             hand.base = malloc(hand.size);
  127.             hand.buf = hand.base;
  128.             if (hand.buf == 0) {
  129.                                 throwException(OutOfMemoryError);
  130.             }
  131.             if (read(fp, hand.buf, hand.size) != hand.size) {
  132.                 abort();
  133.             }
  134.             close(fp);
  135.             readClass(&hand);
  136.             free(hand.base);
  137.             break;
  138.         }
  139.         return;
  140.     }
  141.         throwException(ClassNotFoundException);
  142. }
  143.  
  144. /*
  145.  * Initialise class path.
  146.  */
  147. void
  148. initClasspath(void)
  149. {
  150.     struct stat sbuf;
  151.     char* cp;
  152.     int i;
  153.  
  154.     /* If classpath isn't set, get if from the environment. */
  155.     if (realClassPath == 0) {
  156.         cp = getenv(CLASSPATH);
  157.         if (cp == 0) {
  158. #if defined(DEFAULT_CLASSPATH)
  159.             cp = DEFAULT_CLASSPATH;
  160. #else
  161.             fprintf(stderr, "CLASSPATH is not set!\n");
  162.             exit(1);
  163. #endif
  164.         }
  165.         realClassPath = malloc(strlen(cp) + 1);
  166.         assert(realClassPath != 0);
  167.         strcpy(realClassPath, cp);
  168.     }
  169.     cp = realClassPath;
  170.  
  171. PDBG(    printf("initClasspath(): '%s'\n", cp);                )
  172.     for (i = 0; cp != 0 && i < MAXPATHELEM; i++) {
  173.         classpath[i].path = cp;
  174.         cp = strchr(cp, PATHSEP);
  175.         if (cp != 0) {
  176.             *cp = 0;
  177.             cp++;
  178.         }
  179.         if (stat(classpath[i].path, &sbuf) < 0) {
  180.             classpath[i].type = CP_INVALID;
  181.         }
  182.         else if (S_ISDIR(sbuf.st_mode)) {
  183.             classpath[i].type = CP_DIR;
  184.         }
  185.         else {
  186.             classpath[i].type = CP_FILE;
  187.         }
  188. PDBG(        printf("path '%s' type %d\n", classpath[i].path, classpath[i].type); )
  189.     }
  190.     i++;
  191.     classpath[i].path = 0;
  192. }
  193.