?? jartool.c
字號(hào):
exit(1); } if(add_file_to_jar(jfd, mfd, "META-INF/MANIFEST.MF", &statbuf)){ perror("error writing to jar"); exit(1); } } return 0;}int add_to_jar(int fd, char *new_dir, char *file){ struct stat statbuf; DIR *dir; struct dirent *de; zipentry *ze; int stat_return; char *old_dir = NULL; /* This is a quick compatibility fix -- Simon Weijgers <simon@weijgers.com> * It fixes this: * "normal" jar : org/apache/java/io/LogRecord.class * fastjar : ./org/apache/java/io/LogRecord.class * Fastjar's preservation of the ./'s makes the jarfile unusuable for use * with both kaffe-1.0b4 and JDK. */ while (*file=='.' && *(file+1)=='/') file+=2; /* If new_dir isn't null, we need to change to that directory. However, we also need to return to the old directory when we're done */ if(new_dir != NULL){ old_dir = getcwd(NULL, 0); if(chdir(new_dir) == -1){ perror(new_dir); return 1; } } if(!strcmp(file, jarfile)){ if(verbose) printf("skipping: %s\n", file); return 0; /* we don't want to add ourselves.. */ } stat_return = stat(file, &statbuf); if(stat_return == -1){ perror(file); } else if(S_ISDIR(statbuf.st_mode)){ char *fullname; char *t_ptr; int nlen; unsigned long mod_time; dir = opendir(file); if(dir == NULL){ perror("opendir"); return 1; } nlen = strlen(file) + 256; fullname = (char*)malloc(nlen * sizeof(char)); memset(fullname, 0, (nlen * sizeof(char))); if(fullname == NULL){ fprintf(stderr, "Filename is NULL!\n"); return 1; } strcpy(fullname, file); nlen = strlen(file); if(fullname[nlen - 1] != '/'){ fullname[nlen] = '/'; t_ptr = (fullname + nlen + 1); } else t_ptr = (fullname + nlen); memset((file_header + 12), '\0', 16); /*clear mod time, crc, size fields*/ nlen = (t_ptr - fullname); mod_time = unix2dostime(&statbuf.st_mtime); PACK_UB2(file_header, LOC_EXTRA, 0); PACK_UB2(file_header, LOC_COMP, 0); PACK_UB2(file_header, LOC_FNLEN, nlen); PACK_UB4(file_header, LOC_MODTIME, mod_time); if(verbose) printf("adding: %s (in=%d) (out=%d) (stored 0%%)\n", fullname, 0, 0); ze = (zipentry*)malloc(sizeof(zipentry)); if(ze == NULL){ perror("malloc"); exit(1); } memset(ze, 0, sizeof(zipentry)); /* clear all the fields*/ ze->filename = (char*)malloc((nlen + 1) * sizeof(char) + 1); strcpy(ze->filename, fullname); ze->filename[nlen] = '\0'; ze->offset = lseek(fd, 0, SEEK_CUR); ze->mod_time = (ub2)(mod_time & 0x0000ffff); ze->mod_date = (ub2)((mod_time & 0xffff0000) >> 16); ze->compressed = FALSE; add_entry(ze); write(fd, file_header, 30); write(fd, fullname, nlen); while((de = readdir(dir)) != NULL){ if(de->d_name[0] == '.') continue; if(!strcmp(de->d_name, jarfile)){ /* we don't want to add ourselves. Believe me */ if(verbose) printf("skipping: %s\n", de->d_name); continue; } strcpy(t_ptr, de->d_name); if(add_to_jar(fd, NULL, fullname)){ fprintf(stderr, "Error adding file to jar!\n"); return 1; } } free(fullname); closedir(dir); } else if(S_ISREG(statbuf.st_mode)){ int add_fd; add_fd = open(file, O_RDONLY); if(add_fd < 0){ fprintf(stderr, "Error opening %s.\n", file); return 0; } if(add_file_to_jar(fd, add_fd, file, &statbuf)){ fprintf(stderr, "Error adding file to jar!\n"); return 1; } } else { fprintf(stderr, "Illegal file specified: %s\n", file); } if(old_dir != NULL){ if(chdir(old_dir)) perror(old_dir); free(old_dir); } return 0;}int add_file_to_jar(int jfd, int ffd, char *fname, struct stat *statbuf){ unsigned short file_name_length; unsigned long mod_time; ub1 rd_buff[RDSZ]; uLong crc = 0; off_t offset = 0; int rdamt; struct zipentry *ze; mod_time = unix2dostime(&(statbuf->st_mtime)); file_name_length = strlen(fname); if(!seekable && !do_compress){ crc = crc32(0L, Z_NULL, 0); while((rdamt = read(ffd, rd_buff, RDSZ)) != 0) crc = crc32(crc, rd_buff, rdamt); lseek(ffd, 0, SEEK_SET); } /* data descriptor */ if(!seekable && do_compress){ PACK_UB2(file_header, LOC_EXTRA, 8); } else { PACK_UB2(file_header, LOC_EXTRA, 0); } if(do_compress){ PACK_UB2(file_header, LOC_COMP, 8); } else { PACK_UB2(file_header, LOC_COMP, 0); } PACK_UB4(file_header, LOC_MODTIME, mod_time); PACK_UB2(file_header, LOC_FNLEN, file_name_length); if(!seekable && !do_compress){ PACK_UB4(file_header, LOC_CRC, crc); PACK_UB4(file_header, LOC_USIZE, statbuf->st_size); PACK_UB4(file_header, LOC_CSIZE, statbuf->st_size); } else memset((file_header + LOC_CRC), '\0', 12); /* clear crc/usize/csize */ ze = (zipentry*)malloc(sizeof(zipentry)); if(ze == NULL){ perror("malloc"); exit(1); } memset(ze, 0, sizeof(zipentry)); /* clear all the fields*/ ze->filename = (char*)malloc((file_name_length + 1) * sizeof(char)); strcpy(ze->filename, fname); ze->mod_time = (ub2)(mod_time & 0x0000ffff); ze->mod_date = (ub2)((mod_time & 0xffff0000) >> 16); if(!seekable && !do_compress) ze->crc = crc; ze->csize = statbuf->st_size; ze->usize = ze->csize; ze->offset = lseek(jfd, 0, SEEK_CUR); if(do_compress) ze->compressed = TRUE; else ze->compressed = FALSE; add_entry(ze); /* Write the local header */ write(jfd, file_header, 30); /* write the file name to the zip file */ write(jfd, fname, file_name_length); if(verbose){ printf("adding: %s ", fname); fflush(stdout); } if(do_compress){ /* compress the file */ compress_file(ffd, jfd, ze); } else { /* Write the contents of the file (uncompressed) to the zip file */ /* calculate the CRC as we go along */ ze->crc = crc32(0L, Z_NULL, 0); while((rdamt = read(ffd, rd_buff, RDSZ)) != 0){ ze->crc = crc32(ze->crc, rd_buff, rdamt); if(write(jfd, rd_buff, rdamt) != rdamt){ perror("write"); return 0; } } } close(ffd); /* write out data descriptor */ PACK_UB4(data_descriptor, 4, ze->crc); PACK_UB4(data_descriptor, 8, ze->csize); PACK_UB4(data_descriptor, 12, ze->usize); /* we need to seek back and fill the header */ if(seekable){ offset = (ze->csize + strlen(ze->filename) + 16); if(lseek(jfd, -offset, SEEK_CUR) == (off_t)-1){ perror("lseek"); exit(1); } if(write(jfd, (data_descriptor + 4), 12) != 12){ perror("write"); return 0; } offset -= 12; if(lseek(jfd, offset, SEEK_CUR) == (off_t)-1){ perror("lseek"); exit(1); } } else if(do_compress){ /* Sun's jar tool will only allow a data descriptor if the entry is compressed, but we'll save 16 bytes/entry if we only use it when we can't seek back on the file */ if(write(jfd, data_descriptor, 16) != 16){ perror("write"); return 0; } } if(verbose) printf("(in=%d) (out=%d) (%s %d%%)\n", (int)ze->usize, (int)ze->csize, (do_compress ? "deflated" : "stored"), (do_compress ? ((int)((1 - ze->csize/(float)ze->usize) * 100)) : 0)); return 0;}int create_central_header(int fd){ ub1 header[46]; ub1 end_header[22]; int start_offset; int dir_size; int *iheader; int total_in = 0, total_out = 22; zipentry *ze; iheader = (int*)header; /* magic number */ header[0] = 'P'; header[1] = 'K'; header[2] = 1; header[3] = 2; /* version made by */ header[4] = 10; header[5] = 0; /* version needed to extract */ header[6] = 10; header[7] = 0; /* bit flag */ header[8] = 0; header[9] = 0; /* compression method */ header[10] = 0; header[11] = 0; /* file mod time */ header[12] = 0; header[13] = 0; /* file mod date */ header[14] = 0; header[15] = 0; /* crc 32 */ header[16] = 0; header[17] = 0; header[18] = 0; header[19] = 0; /* compressed size */ header[20] = 0; header[21] = 0; header[22] = 0; header[23] = 0; /* uncompressed size */ header[24] = 0; header[25] = 0; header[26] = 0; header[27] = 0; /* filename length */ header[28] = 0; header[29] = 0; /* extra field length */ header[30] = 0; header[31] = 0; /* file comment length */ header[32] = 0; header[33] = 0; /* disk number start */ header[34] = 0; header[35] = 0; /* internal file attribs */ header[36] = 0; header[37] = 0; /* external file attribs */ header[38] = 0; header[39] = 0; header[40] = 0; header[41] = 0; /* relative offset of local header */ header[42] = 0; header[43] = 0; header[44] = 0; header[45] = 0; start_offset = lseek(fd, 0, SEEK_CUR); for(ze = ziptail; ze != NULL; ze = ze->next_entry){ total_in += ze->usize; total_out += ze->csize + 76 + strlen(ze->filename) * 2; if(ze->compressed){ PACK_UB2(header, CEN_COMP, 8); } else { PACK_UB2(header, CEN_COMP, 0); } PACK_UB2(header, CEN_MODTIME, ze->mod_time); PACK_UB2(header, CEN_MODDATE, ze->mod_date); PACK_UB4(header, CEN_CRC, ze->crc); PACK_UB4(header, CEN_CSIZE, ze->csize); PACK_UB4(header, CEN_USIZE, ze->usize); PACK_UB2(header, CEN_FNLEN, strlen(ze->filename)); PACK_UB4(header, CEN_OFFSET, ze->offset); write(fd, header, 46); write(fd, ze->filename, strlen(ze->filename)); } dir_size = lseek(fd, 0, SEEK_CUR) - start_offset; /* magic number */ end_header[0] = 0x50; end_header[1] = 0x4b; end_header[2] = 0x05; end_header[3] = 0x06; /* number of this disk */ end_header[4] = 0; end_header[5] = 0; /* number of disk w/ start of central header */ end_header[6] = 0; end_header[7] = 0; /* total number of entries in central dir on this disk*/ PACK_UB2(end_header, 8, number_of_entries); /* total number of entries in central dir*/ PACK_UB2(end_header, 10, number_of_entries); /* size of central dir. */ PACK_UB4(end_header, 12, dir_size); /* offset of start of central dir */ PACK_UB4(end_header, 16, start_offset); /* zipfile comment length */ end_header[20] = 0; end_header[21] = 0; write(fd, end_header, 22); if(verbose) printf("Total:\n------\n(in = %d) (out = %d) (%s %d%%)\n", total_in, total_out, (do_compress ? "deflated" : "stored"), (int)((1 - (total_out / (float)total_in)) * 100) ); return 0;}int extract_jar(int fd, char **files, int file_num){ int rdamt; int out_a, in_a; ub4 signature; ub4 csize; ub4 crc; ub2 fnlen; ub2 eflen; ub2 flags; ub2 method; ub1 *filename = NULL; int filename_len = 0; ub4 rd_buff[RDSZ]; pb_file pbf; ub1 scratch[16]; zipentry ze; int f_fd; int dir; int handle; int j; init_inflation(); pb_init(&pbf, fd); for(;;){ f_fd = 0; crc = 0; ze.crc = 0; dir = FALSE; /* by default, the file isn't a dir */ handle = TRUE; /* by default we'll extract/create the file */ if((rdamt = pb_read(&pbf, scratch, 4)) != 4){ perror("read"); break; } signature = UNPACK_UB4(scratch, 0);#ifdef DEBUG printf("signature is %x\n", signature);#endif if(signature == 0x08074b50){#ifdef DEBUG printf("skipping data descriptor\n");#endif pb_read(&pbf, scratch, 12); continue; } else if(signature == 0x02014b50){#ifdef DEBUG printf("Central header reached.. we're all done!\n");#endif break; }else if(signature != 0x04034b50){ printf("Ick! %#x\n", signature); break; } if((rdamt = pb_read(&pbf, (file_header + 4), 26)) != 26){ perror("read"); break; } csize = UNPACK_UB4(file_header, LOC_CSIZE);#ifdef DEBUG printf("Compressed size is %u\n", csize);#endif fnlen = UNPACK_UB2(file_header, LOC_FNLEN);#ifdef DEBUG printf("Filename length is %hu\n", fnlen);#endif eflen = UNPACK_UB2(file_header, LOC_EFLEN);#ifdef DEBUG printf("Extra field length is %hu\n", eflen);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -