📄 jar_support.c
字号:
goto done; } if (memcmp(p + CENHDRSIZ, fname, nameLength) == 0) { if (JAR_DEBUG && verbose) jio_fprintf(stderr, "loadJARfile: Class name found [%s]...\n", fname); break; } } /* Set offset to the next central header */ offset += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p); } /* end loop */ /* p points at the central header for the file */ { unsigned long decompLen = CENLEN(p); /* the decompressed length */ unsigned long compLen = CENSIZ(p); /* the compressed length */ unsigned long method = CENHOW(p); /* how it is stored */ unsigned long expectedCRC = CENCRC(p); /* expected CRC */ unsigned long actualCRC; unsigned char *decompData; /* Make sure file is not encrypted */ if ((CENFLG(p) & 1) == 1) { fprintf(stderr, "Entry is encrypted"); goto done; } jdstream = (JAR_DataStreamPtr)sysMalloc(sizeof(JAR_DataStream) + decompLen); decompData = (unsigned char *)(jdstream + 1); if (/* Go to the beginning of the LOC header */ (fseek(file, entry->jar.locpos + CENOFF(p), SEEK_SET) < 0) /* Read it */ || (fread(p, sizeof(char), LOCHDRSIZ, file) != LOCHDRSIZ) /* Skip over name and extension, if any */ || (fseek(file, LOCNAM(p) + LOCEXT(p), SEEK_CUR) < 0)) { goto done; } switch (method) { case STORED: if (compLen != decompLen) { return NULL; } fread(decompData, sizeof(char), decompLen, file); break; case DEFLATED: { bool_t inflateOK; inflateOK = inflate(file, compLen, decompData, decompLen); if (!inflateOK) { sysFree(jdstream); jdstream = NULL; } break; } default: sysFree(jdstream); jdstream = NULL; break; } actualCRC = jarCRC32(decompData, decompLen); if (actualCRC != expectedCRC) { printf("Unexpected CRC value"); } done: if (file != NULL) { fclose(file); } if (fname != NULL) { sysFree(fname); } if (jdstream != NULL) { jdstream->type = JAR_RESOURCE; jdstream->data = decompData; jdstream->dataLen = decompLen; jdstream->dataIndex = 0; jdstream->mode = JAR_READ; } return jdstream; }}/*========================================================================= * FUNCTION: ReadFromZip() * TYPE: Reads and verifies ZIP file entries * OVERVIEW: Internal function used by ProcessInputs() and recurse_dir. * * This function reads all the Zip entries, and stores them temporarily in * tmpdir. If the ZIP entry read is a class file, then VerifyFile is invoked * to verify the class file. Otherwise, the file read is simply copied over * temporarily to the tmpdir. These are later used for generating a new JAR * file. * * INTERFACE: * parameters: ZipEntry: name of the zip file entry. * returns: nothing *=======================================================================*/voidReadFromZip(zip_t *entry){ unsigned int nameLength; char *filename = NULL; char *p = str_buffer; /* temporary storage */ int offset, nextOffset; int fd; int status; JAR_DataStreamPtr jdstream = NULL; struct stat stat_buf; unsigned char *decompData; unsigned long decompLen; /* the decompressed length */ FILE *file = fopen(entry->name, "rb"); if (file == NULL) { goto done; } if (JAR_DEBUG && verbose) jio_fprintf(stderr, "ReadFromZip: Opened zip file to read classes \n"); /* initialize */ memset(manifestfile, 0, 1024); /* 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 (fread(p + CENHDRSIZ, sizeof(char), nameLength, file) != nameLength) { goto done; } /* initialize the filename with nulls every time */ filename = (char *) sysCalloc(STRINGBUFFERSIZE, nameLength); if (filename == NULL) { fprintf(stderr, "ReadFromZip: Out of memory \n"); exit(1); } memcpy(filename, p + CENHDRSIZ, nameLength); /* We have to calculate nextOffset now, because VerifyFile bashes * str_buffer */ nextOffset = offset + CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "ReadFromZip: filename read %s\n", filename); /* extract the .class from the filename */ if (nameLength > 6 && strcmp(filename + nameLength - 6, ".class") == 0) { /* Verify the class file */ if (JAR_DEBUG && verbose) jio_fprintf(stderr, "ReadFromZip: Extracted '.class' from %s\n", filename); filename[nameLength-6] = 0; if (JAR_DEBUG && verbose) jio_fprintf(stderr, "ReadFromZip: Verifying classfile %s\n", filename); /* call VerifyFile to verify the class */ VerifyFile(filename); } else { /* Read and copy over the file to tmpdir */ /* p points at the central header for the file */ unsigned long compLen = CENSIZ(p); /* the compressed length */ unsigned long method = CENHOW(p); /* how it is stored */ unsigned long expectedCRC = CENCRC(p); /* expected CRC */ unsigned long actualCRC; decompLen = CENLEN(p); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "READFROMZIP: Reading file [%s]...\n", filename); /* Make sure file is not encrypted */ if ((CENFLG(p) & 1) == 1) { jio_fprintf(stderr, "Entry is encrypted\n"); goto done; } jdstream = (JAR_DataStreamPtr)sysMalloc(sizeof(JAR_DataStream) + decompLen); decompData = (unsigned char *)(jdstream + 1); if (/* Go to the beginning of the LOC header */ (fseek(file, entry->jar.locpos + CENOFF(p), SEEK_SET) < 0) /* Read it */ || (fread(p, sizeof(char), LOCHDRSIZ, file) != LOCHDRSIZ) /* Skip over name and extension, if any */ || (fseek(file, LOCNAM(p) + LOCEXT(p), SEEK_CUR) < 0)) { goto done; } switch (method) { case STORED: if (compLen != decompLen) { sysFree(jdstream); jdstream = NULL; goto done; } fread(decompData, sizeof(char), decompLen, file); break; case DEFLATED: { bool_t inflateOK; inflateOK = inflate(file, compLen, decompData, decompLen); if (!inflateOK) { sysFree(jdstream); jdstream = NULL; } break; } default: sysFree(jdstream); jdstream = NULL; break; } actualCRC = jarCRC32(decompData, decompLen); if (actualCRC != expectedCRC) { jio_fprintf(stderr, "Unexpected CRC value\n"); } /* create the tempdir if it doesn't already exist */ { char fname[1024]; /* file name restored from JAR */ char *dir; char *q; char *sfname = fname; /* system-specific file name */ char *dname = fname; /* destination file name */ if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Reading filename [%s] from JAR \n", filename); sprintf(fname, "%s%c%s", tmp_dir, (char) LOCAL_DIR_SEPARATOR, filename); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Before conversion: fname [%s] sfname [%s]\n", fname, sfname); /* * convert JAR name to the system-specific file name */ sfname = JARname2fname(fname, dname, strlen(fname)+1); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "After conversion: Converted [%s] to [%s]\n", fname, sfname); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Preparing to write file [%s]\n", sfname); dir = strdup(sfname); q = strrchr(dir, (char)LOCAL_DIR_SEPARATOR); if (q) { *q = 0; ensure_tmpdir_exists(dir); } free(dir); /* Attempt to stat or open only if this is NOT a directory */ if (!(sfname[strlen(sfname)-1] == (char)LOCAL_DIR_SEPARATOR)) { if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Attempting stat on dir [%s]\n", sfname); status = stat(sfname, &stat_buf); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Status from stat of [%s] is %d\n", sfname, status); /* Attempt to open only if the file does not already exist. * This is indicated by the stat command returning -1. * And this is not a directory. */ if ((status < 0) || !(stat_buf.st_mode & S_IFDIR)) { if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Opening file [%s]\n", sfname);#ifdef UNIX fd = open(sfname, O_WRONLY | O_CREAT | O_TRUNC , 0644);#endif#ifdef WIN32 fd = open(sfname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);#endif if (fd < 0) { panic("failed to open %s", sfname); } if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Writing file [%s]...\n", sfname); /* write the file to the tmpdir just created */ write(fd, decompData, decompLen); /* check for the JAR Manifest.mf file */ if (isManifestfile(sfname, strlen(sfname))) { /* save it for using it later to create * the JAR file */ memcpy(manifestfile, sfname + strlen(tmp_dir), strlen(sfname)); if (JAR_DEBUG && verbose) jio_fprintf(stderr, "Saving JAR manifest file [%s]\n", manifestfile); } close(fd); } } } if (jdstream != NULL) { sysFree(jdstream); jdstream = NULL; } } /* Set offset to the next central header */ offset = nextOffset; sysFree(filename); filename = NULL; }done: if (file != NULL) { fclose(file); } if (jdstream != NULL) { jdstream->type = JAR_RESOURCE; jdstream->data = decompData; jdstream->dataLen = decompLen; jdstream->dataIndex = 0; jdstream->mode = JAR_READ; } if (filename != NULL) sysFree(filename);}/*========================================================================= * FUNCTION: remove_dir() * TYPE: Handles removing files from recursive directories * OVERVIEW: Internal function called by ProcessJARfile(). * * This function reads a directory, searching for either another directory, * or an individual class name that is to be removed using the remove() * API call. * * INTERFACE: * parameters: dirname name of the directory entry. * pkgname name of the package * returns: nothing *=======================================================================*/static void remove_dir(char *dirname, char *pkgname){ struct dirent *ent; char buf[MAXPACKAGENAME]; char pkgbuf[MAXPACKAGENAME]; char tmpbuf[MAXPACKAGENAME]; char tmppkg[MAXPACKAGENAME]; char tmppkgbuf[MAXPACKAGENAME]; char *name = NULL; DIR *dir = opendir(dirname); int err = 0; int status; /* Initialize the buffers to 0 */ memset(buf, 0, sizeof(buf)); memset(pkgbuf, 0, sizeof(pkgbuf)); memset(tmpbuf, 0, sizeof(tmpbuf)); memset(tmppkg, 0, sizeof(tmppkg)); memset(tmppkgbuf, 0, sizeof(tmppkgbuf)); if (dir == NULL) { fprintf(stderr, "Can't open dir %s\n", dirname); exit(1); } for (ent = readdir(dir); ent; ent = readdir(dir)) { struct stat stat_buf; int len; name = ent->d_name; if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { continue; } strcpy(pkgbuf, pkgname); if (pkgname[0] != 0) { /* concatenate '/' to the package name */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -