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

📄 jartool.c

📁 jar文件处理原程序
💻 C
📖 第 1 页 / 共 3 页
字号:
      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);

⌨️ 快捷键说明

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