⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jar_support.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#)jar_support.c  1.24 01/07/19 * * Copyright 1997, 1998 by Sun Microsystems, Inc., * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. * All rights reserved. * * This software is the confidential and proprietary information * of Sun Microsystems, Inc. ("Confidential Information").  You * shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with Sun. * Use is subject to license terms. *//*========================================================================= * SYSTEM:    Verifier * SUBSYSTEM: JAR support routines for the verifier. * FILE:      jar_support.c * OVERVIEW:  JAR support routines for verifying class files from a ZIP or *            JAR file. *            Note that the JAR file reader used is based on the KVM *            implementation with some modifications. * AUTHOR:    Tasneem Sayeed, Java Consumer Technologies, Sun Microsystems *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <string.h>#include <sys_api.h>#include <path_md.h>#include <path.h>#include <oobj.h>#include <jar.h>#include <convert_md.h>#include <string.h>#ifdef WIN32#include <process.h>#endif/*========================================================================= * Globals and extern declarations *=======================================================================*/extern int errno;char str_buffer[STRINGBUFFERSIZE];   /*  shared string buffer */bool_t JARfile = FALSE;    /* if true, indicates that output is in a                                                  JAR file */extern bool_t tmpDirExists;                           /* if true, indicates that a temp dir exists                              with classes to be verified */char *zipFileName = NULL;  /* stores name of the zip file */extern char tmp_dir[32];   /* temporary directory for storing                                                  verified classes */extern char *output_dir;   /* output directory */char manifestfile[1024];   /* used for saving the JAR manifest file name */extern void VerifyFile(register char *fn);/*========================================================================= * FUNCTION:      isJARfile * OVERVIEW:      Determines if the given file is a JAR or ZIP file. *                Returns true if the suffix ends with ".jar" or ".zip". * INTERFACE: *   parameters:  fn:      name of the JAR file *                length:  length of data, in bytes *   returns:     boolean type *=======================================================================*/bool_tisJARfile (char *fn, int length){    char *suffix;    if (length >= 4 &&       (( suffix = fn + length - 4)[0] == '.') &&         ((( _toupper(suffix[1]) == 'Z') &&          ( _toupper(suffix[2]) == 'I') &&          ( _toupper(suffix[3]) == 'P')) ||         (( _toupper(suffix[1]) == 'J') &&          ( _toupper(suffix[2]) == 'A') &&          ( _toupper(suffix[3]) == 'R')))) {        return TRUE;    } else {        return FALSE;    }}/*========================================================================= * FUNCTION:      isManifestfile * OVERVIEW:      Determines if the given file is a JAR Manifest file. *                Returns true if the file ends with "MANIFEST.MF". * INTERFACE: *   parameters:  fn:      name of the JAR manifest file *                length:  length of data, in bytes *   returns:     boolean type *=======================================================================*/bool_tisManifestfile (char *fn, int length){    if ((length >= 11) &&       (strcmp(fn + length - 11, "MANIFEST.MF") == 0)) {        return TRUE;    } else {        return FALSE;    }}/*========================================================================= * FUNCTION:      ensure_tmpdir_exists * OVERVIEW:      Validates to ensure that the tmpdir exists using the *                system-specific directory delimiters. * * INTERFACE: *   parameters:  char* dir name *   returns:     nothing *=======================================================================*/void ensure_tmpdir_exists(char *dir){    struct stat stat_buf;    char *parent;    char *q;    if (dir[0] == 0) {        return;    }    parent = strdup(dir);    q = strrchr(parent, (char)LOCAL_DIR_SEPARATOR);    if (q) {        *q = 0;        ensure_tmpdir_exists(parent);    }    if (stat(dir, &stat_buf) < 0) {        if (JAR_DEBUG && verbose) {            jio_fprintf(stderr, "Creating output directory [%s]\n", dir);        }#ifdef WIN32        mkdir(dir);#endif#ifdef UNIX        mkdir(dir, 0755);#endif    }    free(parent);}/*========================================================================= * FUNCTION:      JARname2fname * OVERVIEW:      Converts JAR name to the system-specific file name with *                the correct directory delimiters. * * INTERFACE: *   parameters:  char* source JAR name *                char* dest file name *                int size *   returns:     char* *=======================================================================*/char*JARname2fname(char *src, char *dst, int size) {    char *buf = dst;    for (; (--size > 0) && (*src != '\0') ; src++, dst++) {    if (*src == '/') {        *dst = (char)LOCAL_DIR_SEPARATOR;    }  else {        *dst = *src;    }    }    dst++;    *dst = '\0';    return buf;}/*========================================================================= * FUNCTION:      getZipEntry * OVERVIEW:      Converts a zip file to a Zip entry type. * INTERFACE: *   parameters:  zipFile:      name of the JAR file *                len:          length of data, in bytes *   returns:     zip entry type *=======================================================================*/zip_t *getZipEntry (char *zipFile, int len) {    zip_t * zipEntry = NULL;  /* for processing errors */    if (JAR_DEBUG && verbose)        jio_fprintf(stderr,            "getZipEntry: JAR file [%s] Size [%d]\n", zipFile, len);    /* create the zip entry for loading the ZIP file */    zipEntry = (zip_t *) sysMalloc(sizeof(zip_t) + len);    if (zipEntry == NULL) {        fprintf(stderr, "getZipEntry: Out of memory\n");        exit(1);    }    memcpy(zipEntry->name, zipFile, len);    zipEntry->name[len] = '\0';    if (JAR_DEBUG && verbose)        jio_fprintf(stderr, "getZipEntry: Zip Entry Name [%s]\n", zipEntry->name);    zipEntry->type = '\0';    return zipEntry;}/*========================================================================= * FUNCTION:      findJARDirectories * OVERVIEW:      Helper function used for JAR loading for locating JAR *                directories. *                It returns TRUE if it is successful in locating the *                JAR directory headers, false otherwise. *                If successful, *                entry->jar.locpos is set to the position of the first *                local header. *                entry->jar.cenpos is set to the position of the first *                central header. * *                Note that *locpos pointer is the logical "0" of the file. *                All offsets extracted need to have this value added to them. * * INTERFACE: *   parameters:  entry:     zipFileEntry *                statbuf:   pointer to the stat buffer *   returns:     boolean type *=======================================================================*/bool_tfindJARDirectories(zip_t *entry, struct stat *statbuf){    bool_t result = FALSE;    long length = statbuf->st_size;    long position, minPosition;    char *bp;    FILE *file;    char *buffer = str_buffer;    unsigned const int bufferSize = STRINGBUFFERSIZE;    /* Calculate the smallest possible position for the end header.  It     * can be at most 0xFFFF + ENDHDRSIZ bytes from the end of the file, but     * the file must also have a local header and a central header     */    minPosition = length - (0xFFFF + ENDHDRSIZ);    if (minPosition < LOCHDRSIZ + CENHDRSIZ) {        minPosition = LOCHDRSIZ + CENHDRSIZ;    }    file = fopen(entry->name, "rb");    if (file == NULL) {        goto done;    }    /* Read in the last ENDHDRSIZ bytes into the buffer.  99% of the time,     * the file won't have a comment, and this is the only read we'll need */    if (   (fseek(file, -ENDHDRSIZ, SEEK_END) < 0)        || (fread(buffer, sizeof(char), ENDHDRSIZ, file) != ENDHDRSIZ)) {        goto done;    }    /* Get the position in the file stored into buffer[0] */    position = length - ENDHDRSIZ;  /* Position in file of buffer[0] */    bp = buffer;            /* Where to start looking */    for (;;) {        /* "buffer" contains a block of data from the file, starting at         * position "position" in the file.         * We investigate whether   position + (bp - buffer)  is the start         * of the end header in the zip file.  This file position is at         * position bp in the buffer.         */        /* Use simplified version of Knuth Morris Pratt search algorithm. */        switch(bp[0]) {            case '\006':   /* The header must start at least 3 bytes back */                bp -= 3; break;            case '\005':   /* The header must start at least 2 bytes back  */                bp -= 2; break;            case 'K':      /* The header must start at least 1 byte back  */                bp -= 1; break;            case 'P':      /* Either this is the header, or the header must                            * start at least 4  back                            */                if (bp[1] == 'K' && bp[2] == 5 && bp[3] == 6) {                    int endpos = position + (bp - buffer);                    if (endpos + ENDHDRSIZ + ENDCOM(bp) == length) {                        unsigned long cenpos = endpos - ENDSIZ(bp);                        unsigned long locpos = cenpos - ENDOFF(bp);                        entry->jar.cenpos = cenpos;                        entry->jar.locpos = locpos;                        result = TRUE;                        goto done;                    }                }            /* FALL THROUGH */            default:      /* This char isn't in the header signature, so                           * the header must start at least four chars back */                bp -= 4;        }        if (bp < buffer) {            /* We've moved outside our window into the file.  We must             * move the window backwards */            int count = position - minPosition; /* Bytes left in file */            if (count == 0) {                /* Nothing left to read.  Time to give up */                goto done;            } else {                /* up to ((bp - buffer) + ENDHDRSIZ) bytes in the buffer might                 * still be part of the end header, so the most bytes we can                 * actually read are                 *      bufferSize - ((bp - buffer) + ENDHDRSIZE).                 */                int available = (bufferSize - ENDHDRSIZ) + (buffer - bp);                if (count > available) {                    count = available;                }            }            /* Back up, while keeping our virtual position the same */            position -= count;            bp += count;            memmove(buffer + count, buffer, bufferSize - count);            if (   (fseek(file, position, SEEK_SET) < 0)              || (fread(buffer, sizeof(char), count, file) != (unsigned)count)) {                goto done;            }        }    } /* end of for loop */ done:    if (file != NULL) {        fclose(file);    }    return result;}/*========================================================================= * FUNCTION:      jarCRC32 * OVERVIEW:      Returns the CRC of an array of bytes, using the same *                algorithm as used by the JAR reader. * INTERFACE: *   parameters:  data:     pointer to the array of bytes *                length:   length of data, in bytes *   returns:     CRC *=======================================================================*/static unsigned longjarCRC32(unsigned char *data, unsigned long length) {    unsigned long crc = 0xFFFFFFFF;    unsigned int j;    for ( ; length > 0; length--, data++) {        crc ^= *data;        for (j = 8; j > 0; --j) {        crc = (crc & 1) ? ((crc >> 1) ^ 0xedb88320) : (crc >> 1);        }    }    return ~crc;}/*========================================================================= * FUNCTION:      loadJARfile() * TYPE:          load JAR file * OVERVIEW:      Internal function used by openClassfileInternal(). * *  This function reads the specified class file from the JAR file.  The *  result is returned as a JAR_DataStream*.  NULL is returned if it *  cannot find the file, or there is some error. * * INTERFACE: *   parameters:  entry:    zip file entry for the JAR file *                filename: class file name to search for *   returns:     JAR_DataStream* for saving the JAR file info, or NULL. *=======================================================================*/JAR_DataStreamPtrloadJARfile(zip_t *entry, const char* filename){    JAR_DataStreamPtr jdstream = NULL; /* result on error */    unsigned int filenameLength;    unsigned int nameLength;    char buff[BUFSIZ];    char *UTFfilename = &buff[0];    char *p = str_buffer;   /* temporary storage */    int offset;    char *fname = NULL;    FILE *file = fopen(entry->name, "rb");    if (file == NULL) {        goto done;    }    if (JAR_DEBUG && verbose)        jio_fprintf(stderr,               "loadJARfile: Opening zip file %s to search for [%s]\n",                entry->name, filename);    /* add the .class to the filename */    if (JAR_DEBUG && verbose)        jio_fprintf(stderr,        "loadJARfile: Adding '.class' to %s size [%d]\n", filename, strlen(filename));    /* Conversion for Japanese filenames */    native2utf8(filename, UTFfilename, BUFSIZ);    /* allocate fname large enough to hold .class + '\0' terminator */    fname = (char *)malloc(strlen(UTFfilename) + 6 + 1);    sprintf(fname, "%s.class", UTFfilename);    filenameLength=strlen(fname);    fname[filenameLength]='\0';    if (JAR_DEBUG && verbose)        jio_fprintf(stderr,        "loadJARfile: Searching for filename [%s]\n", fname);    /* Go to the start of the central headers */    offset = entry->jar.cenpos;    for (;;) {        if (/* Go to the next central header */            (fseek(file, offset, SEEK_SET) < 0)            /* Read the bytes */        || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ)            /* Make sure it is a header */        || (GETSIG(p) != CENSIG)) {            goto done;        }        /* Get the nameLength */        nameLength = CENNAM(p);        if (nameLength == filenameLength) {            if (fread(p + CENHDRSIZ, sizeof(char), nameLength, file)                     != nameLength) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -