864 if (zip->msg != NULL)
865 *pmsg = strdup(zip->msg);
866 }
867 freeZip(zip);
868 return NULL;
869 }
870 MLOCK(zfiles_lock);
871 zip->next = zfiles;
872 zfiles = zip;
873 MUNLOCK(zfiles_lock);
874
875 return zip;
876 }
877
878 /*
879 * Opens a zip file for reading. Returns the jzfile object or NULL
880 * if an error occurred. If a zip error occurred then *msg will be
881 * set to the error message text if msg != 0. Otherwise, *msg will be
882 * set to NULL. Caller doesn't need to free the error message.
883 */
884 JNIEXPORT jzfile * JNICALL
885 ZIP_Open(const char *name, char **pmsg)
886 {
887 jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
888 if (file == NULL && pmsg != NULL && *pmsg != NULL) {
889 free(*pmsg);
890 *pmsg = "Zip file open error";
891 }
892 return file;
893 }
894
895 /*
896 * Closes the specified zip file object.
897 */
898 JNIEXPORT void JNICALL
899 ZIP_Close(jzfile *zip)
900 {
901 MLOCK(zfiles_lock);
902 if (--zip->refs > 0) {
903 /* Still more references so just return */
904 MUNLOCK(zfiles_lock);
905 return;
906 }
907 /* No other references so close the file and remove from list */
908 if (zfiles == zip) {
909 zfiles = zfiles->next;
910 } else {
911 jzfile *zp;
912 for (zp = zfiles; zp->next != 0; zp = zp->next) {
913 if (zp->next == zip) {
914 zp->next = zip->next;
915 break;
916 }
917 }
918 }
1098 ZIP_FreeEntry(jzfile *jz, jzentry *ze)
1099 {
1100 jzentry *last;
1101 ZIP_Lock(jz);
1102 last = jz->cache;
1103 jz->cache = ze;
1104 ZIP_Unlock(jz);
1105 if (last != NULL) {
1106 /* Free the previously cached jzentry */
1107 free(last->name);
1108 if (last->extra) free(last->extra);
1109 if (last->comment) free(last->comment);
1110 free(last);
1111 }
1112 }
1113
1114 /*
1115 * Returns the zip entry corresponding to the specified name, or
1116 * NULL if not found.
1117 */
1118 JNIEXPORT jzentry * JNICALL
1119 ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
1120 {
1121 if (ulen == 0) {
1122 return ZIP_GetEntry2(zip, name, (jint)strlen(name), JNI_FALSE);
1123 }
1124 return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE);
1125 }
1126
1127 jboolean equals(char* name1, int len1, char* name2, int len2) {
1128 if (len1 != len2) {
1129 return JNI_FALSE;
1130 }
1131 while (len1-- > 0) {
1132 if (*name1++ != *name2++) {
1133 return JNI_FALSE;
1134 }
1135 }
1136 return JNI_TRUE;
1137 }
1138
1221 break;
1222 }
1223
1224 /* Add slash and try once more */
1225 name[ulen++] = '/';
1226 name[ulen] = '\0';
1227 hsh = hash_append(hsh, '/');
1228 idx = zip->table[hsh % zip->tablelen];
1229 addSlash = JNI_FALSE;
1230 }
1231
1232 Finally:
1233 ZIP_Unlock(zip);
1234 return ze;
1235 }
1236
1237 /*
1238 * Returns the n'th (starting at zero) zip file entry, or NULL if the
1239 * specified index was out of range.
1240 */
1241 JNIEXPORT jzentry * JNICALL
1242 ZIP_GetNextEntry(jzfile *zip, jint n)
1243 {
1244 jzentry *result;
1245 if (n < 0 || n >= zip->total) {
1246 return 0;
1247 }
1248 ZIP_Lock(zip);
1249 result = newEntry(zip, &zip->entries[n], ACCESS_SEQUENTIAL);
1250 ZIP_Unlock(zip);
1251 return result;
1252 }
1253
1254 /*
1255 * Locks the specified zip file for reading.
1256 */
1257 JNIEXPORT void JNICALL
1258 ZIP_Lock(jzfile *zip)
1259 {
1260 MLOCK(zip->lock);
1261 }
1422 if (count != 0 || strm.total_out != (uInt)entry->size) {
1423 *msg = "inflateFully: Unexpected end of stream";
1424 inflateEnd(&strm);
1425 return JNI_FALSE;
1426 }
1427 break;
1428 default:
1429 break;
1430 }
1431 } while (strm.avail_in > 0);
1432 }
1433
1434 inflateEnd(&strm);
1435 return JNI_TRUE;
1436 }
1437
1438 /*
1439 * The current implementation does not support reading an entry that
1440 * has the size bigger than 2**32 bytes in ONE invocation.
1441 */
1442 JNIEXPORT jzentry * JNICALL
1443 ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP)
1444 {
1445 jzentry *entry = ZIP_GetEntry(zip, name, 0);
1446 if (entry) {
1447 *sizeP = (jint)entry->size;
1448 *nameLenP = (jint)strlen(entry->name);
1449 }
1450 return entry;
1451 }
1452
1453 /*
1454 * Reads a zip file entry into the specified byte array
1455 * When the method completes, it releases the jzentry.
1456 * Note: this is called from the separately delivered VM (hotspot/classic)
1457 * so we have to be careful to maintain the expected behaviour.
1458 */
1459 JNIEXPORT jboolean JNICALL
1460 ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
1461 {
1462 char *msg;
1463 char tmpbuf[1024];
1464
1465 if (entry == 0) {
1466 jio_fprintf(stderr, "jzentry was invalid");
1467 return JNI_FALSE;
1468 }
1469
1470 strcpy(entryname, entry->name);
1471 if (entry->csize == 0) {
1472 /* Entry is stored */
1473 jlong pos = 0;
1474 jlong size = entry->size;
1475 while (pos < size) {
1476 jint n;
1477 jlong limit = ((((jlong) 1) << 31) - 1);
1478 jint count = (size - pos < limit) ?
1479 /* These casts suppress a VC++ Internal Compiler Error */
1498 /* Entry is compressed */
1499 int ok = InflateFully(zip, entry, buf, &msg);
1500 if (!ok) {
1501 if ((msg == NULL) || (*msg == 0)) {
1502 msg = zip->msg;
1503 }
1504 if (msg == 0) {
1505 getErrorString(errno, tmpbuf, sizeof(tmpbuf));
1506 msg = tmpbuf;
1507 }
1508 jio_fprintf(stderr, "%s: %s\n", zip->name, msg);
1509 return JNI_FALSE;
1510 }
1511 }
1512
1513 ZIP_FreeEntry(zip, entry);
1514
1515 return JNI_TRUE;
1516 }
1517
1518 JNIEXPORT jboolean JNICALL
1519 ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg)
1520 {
1521 z_stream strm;
1522 int i = 0;
1523 memset(&strm, 0, sizeof(z_stream));
1524
1525 *pmsg = 0; /* Reset error message */
1526
1527 if (inflateInit2(&strm, MAX_WBITS) != Z_OK) {
1528 *pmsg = strm.msg;
1529 return JNI_FALSE;
1530 }
1531
1532 strm.next_out = (Bytef *) outBuf;
1533 strm.avail_out = (uInt)outLen;
1534 strm.next_in = (Bytef *) inBuf;
1535 strm.avail_in = (uInt)inLen;
1536
1537 do {
1538 switch (inflate(&strm, Z_PARTIAL_FLUSH)) {
|
864 if (zip->msg != NULL)
865 *pmsg = strdup(zip->msg);
866 }
867 freeZip(zip);
868 return NULL;
869 }
870 MLOCK(zfiles_lock);
871 zip->next = zfiles;
872 zfiles = zip;
873 MUNLOCK(zfiles_lock);
874
875 return zip;
876 }
877
878 /*
879 * Opens a zip file for reading. Returns the jzfile object or NULL
880 * if an error occurred. If a zip error occurred then *msg will be
881 * set to the error message text if msg != 0. Otherwise, *msg will be
882 * set to NULL. Caller doesn't need to free the error message.
883 */
884 JNIEXPORT jzfile *
885 ZIP_Open(const char *name, char **pmsg)
886 {
887 jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
888 if (file == NULL && pmsg != NULL && *pmsg != NULL) {
889 free(*pmsg);
890 *pmsg = "Zip file open error";
891 }
892 return file;
893 }
894
895 /*
896 * Closes the specified zip file object.
897 */
898 JNIEXPORT void
899 ZIP_Close(jzfile *zip)
900 {
901 MLOCK(zfiles_lock);
902 if (--zip->refs > 0) {
903 /* Still more references so just return */
904 MUNLOCK(zfiles_lock);
905 return;
906 }
907 /* No other references so close the file and remove from list */
908 if (zfiles == zip) {
909 zfiles = zfiles->next;
910 } else {
911 jzfile *zp;
912 for (zp = zfiles; zp->next != 0; zp = zp->next) {
913 if (zp->next == zip) {
914 zp->next = zip->next;
915 break;
916 }
917 }
918 }
1098 ZIP_FreeEntry(jzfile *jz, jzentry *ze)
1099 {
1100 jzentry *last;
1101 ZIP_Lock(jz);
1102 last = jz->cache;
1103 jz->cache = ze;
1104 ZIP_Unlock(jz);
1105 if (last != NULL) {
1106 /* Free the previously cached jzentry */
1107 free(last->name);
1108 if (last->extra) free(last->extra);
1109 if (last->comment) free(last->comment);
1110 free(last);
1111 }
1112 }
1113
1114 /*
1115 * Returns the zip entry corresponding to the specified name, or
1116 * NULL if not found.
1117 */
1118 JNIEXPORT jzentry *
1119 ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
1120 {
1121 if (ulen == 0) {
1122 return ZIP_GetEntry2(zip, name, (jint)strlen(name), JNI_FALSE);
1123 }
1124 return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE);
1125 }
1126
1127 jboolean equals(char* name1, int len1, char* name2, int len2) {
1128 if (len1 != len2) {
1129 return JNI_FALSE;
1130 }
1131 while (len1-- > 0) {
1132 if (*name1++ != *name2++) {
1133 return JNI_FALSE;
1134 }
1135 }
1136 return JNI_TRUE;
1137 }
1138
1221 break;
1222 }
1223
1224 /* Add slash and try once more */
1225 name[ulen++] = '/';
1226 name[ulen] = '\0';
1227 hsh = hash_append(hsh, '/');
1228 idx = zip->table[hsh % zip->tablelen];
1229 addSlash = JNI_FALSE;
1230 }
1231
1232 Finally:
1233 ZIP_Unlock(zip);
1234 return ze;
1235 }
1236
1237 /*
1238 * Returns the n'th (starting at zero) zip file entry, or NULL if the
1239 * specified index was out of range.
1240 */
1241 JNIEXPORT jzentry *
1242 ZIP_GetNextEntry(jzfile *zip, jint n)
1243 {
1244 jzentry *result;
1245 if (n < 0 || n >= zip->total) {
1246 return 0;
1247 }
1248 ZIP_Lock(zip);
1249 result = newEntry(zip, &zip->entries[n], ACCESS_SEQUENTIAL);
1250 ZIP_Unlock(zip);
1251 return result;
1252 }
1253
1254 /*
1255 * Locks the specified zip file for reading.
1256 */
1257 JNIEXPORT void JNICALL
1258 ZIP_Lock(jzfile *zip)
1259 {
1260 MLOCK(zip->lock);
1261 }
1422 if (count != 0 || strm.total_out != (uInt)entry->size) {
1423 *msg = "inflateFully: Unexpected end of stream";
1424 inflateEnd(&strm);
1425 return JNI_FALSE;
1426 }
1427 break;
1428 default:
1429 break;
1430 }
1431 } while (strm.avail_in > 0);
1432 }
1433
1434 inflateEnd(&strm);
1435 return JNI_TRUE;
1436 }
1437
1438 /*
1439 * The current implementation does not support reading an entry that
1440 * has the size bigger than 2**32 bytes in ONE invocation.
1441 */
1442 JNIEXPORT jzentry *
1443 ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP)
1444 {
1445 jzentry *entry = ZIP_GetEntry(zip, name, 0);
1446 if (entry) {
1447 *sizeP = (jint)entry->size;
1448 *nameLenP = (jint)strlen(entry->name);
1449 }
1450 return entry;
1451 }
1452
1453 /*
1454 * Reads a zip file entry into the specified byte array
1455 * When the method completes, it releases the jzentry.
1456 * Note: this is called from the separately delivered VM (hotspot/classic)
1457 * so we have to be careful to maintain the expected behaviour.
1458 */
1459 JNIEXPORT jboolean
1460 ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
1461 {
1462 char *msg;
1463 char tmpbuf[1024];
1464
1465 if (entry == 0) {
1466 jio_fprintf(stderr, "jzentry was invalid");
1467 return JNI_FALSE;
1468 }
1469
1470 strcpy(entryname, entry->name);
1471 if (entry->csize == 0) {
1472 /* Entry is stored */
1473 jlong pos = 0;
1474 jlong size = entry->size;
1475 while (pos < size) {
1476 jint n;
1477 jlong limit = ((((jlong) 1) << 31) - 1);
1478 jint count = (size - pos < limit) ?
1479 /* These casts suppress a VC++ Internal Compiler Error */
1498 /* Entry is compressed */
1499 int ok = InflateFully(zip, entry, buf, &msg);
1500 if (!ok) {
1501 if ((msg == NULL) || (*msg == 0)) {
1502 msg = zip->msg;
1503 }
1504 if (msg == 0) {
1505 getErrorString(errno, tmpbuf, sizeof(tmpbuf));
1506 msg = tmpbuf;
1507 }
1508 jio_fprintf(stderr, "%s: %s\n", zip->name, msg);
1509 return JNI_FALSE;
1510 }
1511 }
1512
1513 ZIP_FreeEntry(zip, entry);
1514
1515 return JNI_TRUE;
1516 }
1517
1518 JNIEXPORT jboolean
1519 ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg)
1520 {
1521 z_stream strm;
1522 int i = 0;
1523 memset(&strm, 0, sizeof(z_stream));
1524
1525 *pmsg = 0; /* Reset error message */
1526
1527 if (inflateInit2(&strm, MAX_WBITS) != Z_OK) {
1528 *pmsg = strm.msg;
1529 return JNI_FALSE;
1530 }
1531
1532 strm.next_out = (Bytef *) outBuf;
1533 strm.avail_out = (uInt)outLen;
1534 strm.next_in = (Bytef *) inBuf;
1535 strm.avail_in = (uInt)inLen;
1536
1537 do {
1538 switch (inflate(&strm, Z_PARTIAL_FLUSH)) {
|