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

📄 jartool.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (jarfd != STDIN_FILENO && close(jarfd) != 0) {      fprintf(stderr, "%s: error closing jar archive: %s\n",	      progname, strerror (errno));      exit (1);    }  } else if(action == ACTION_LIST){    list_jar(jarfd, &new_argv[0], new_argc);  } else if(action == ACTION_EXTRACT){    extract_jar(jarfd, &new_argv[0], new_argc);  }    exit(0);}static int args_current_g;static char **args_g;static void init_args(args, current)     char **args;     int current;{  if(!read_names_from_stdin)    {      args_g = args;      args_current_g = current;    }}static char *get_next_arg (){  static int reached_end = 0;  if (reached_end)    return NULL;  if (args_g)    {      if (!args_g [args_current_g])	{	  reached_end = 1;	  return NULL;	}      return args_g [args_current_g++];    }  else    {      /* Read the name from stdin. Delimiters are '\n' and	 '\r'. Reading EOF indicates that we don't have anymore file	 names characters to read. */      char s [MAXPATHLEN];      int  pos = 0;      /* Get rid of '\n' and '\r' first. */      while (1)	{	  int c = getc (stdin);	  if (c == '\n' || c == '\r')	    continue;	  else	    {	      if (c == EOF)		return NULL;	      ungetc (c, stdin);	      break;	    }	}      while (1)	{	  int c = getc (stdin);	  /* Exit when we get a delimiter or don't have any characters             to read */	  if (c == '\n'|| c == '\r'|| c == EOF)	    break;	  s [pos++] = (char) c;	}      if (pos)	{	  s [pos] = '\0';	  return jt_strdup (s);	}      else	return NULL;    }}void init_headers(){  /* packing file header */  /* magic number */  file_header[0] = 0x50;  file_header[1] = 0x4b;  file_header[2] = 0x03;  file_header[3] = 0x04;  /* version number (Unix 1.0)*/  file_header[4] = 10;  file_header[5] = 0;  /* bit flag (normal deflation)*/  file_header[6] = 0x00;  file_header[7] = 0x00;  /* do_compression method (deflation) */  file_header[8] = 0;  file_header[9] = 0;  /* last mod file time (MS-DOS format) */  file_header[10] = 0;  file_header[11] = 0;  /* last mod file date (MS-DOS format) */  file_header[12] = 0;  file_header[13] = 0;  /* CRC 32 */  file_header[14] = 0;  file_header[15] = 0;  file_header[16] = 0;  file_header[17] = 0;  /* compressed size */  file_header[18] = 0;  file_header[19] = 0;  file_header[20] = 0;  file_header[21] = 0;  /* uncompressed size */  file_header[22] = 0;  file_header[23] = 0;  file_header[24] = 0;  file_header[25] = 0;  /* filename length */  file_header[26] = 0;  file_header[27] = 0;  /* extra field length */  file_header[28] = 0;  file_header[29] = 0;  /* Initialize the compression DS */  PACK_UB4(data_descriptor, 0, 0x08074b50);  }void add_entry(struct zipentry *ze){  if(ziplist == NULL){    ziplist = ze;    ziptail = ziplist;  } else {    ziplist->next_entry = ze;    ziplist = ze;  }    number_of_entries++;}static struct zipentry *find_entry (const char *fname){  struct zipentry *ze;  for (ze = ziptail; ze; ze = ze->next_entry)    {      if (!strcmp (ze->filename, fname))	return ze;    }  return NULL;}static intlooks_like_dir (const char *fname){  struct zipentry *ze;  size_t len = strlen (fname);  for (ze = ziptail; ze; ze = ze->next_entry)    {      if (strlen (ze->filename) > len	  && !strncmp (fname, ze->filename, len)	  && ze->filename[len] == '/')	return 1;    }  return 0;}/* * Read the zip entries of an existing file, building `ziplist' as we go. */int read_entries (int fd){  struct zipentry *ze;  ub1 intbuf[4];  ub1 header[46];  ub2 len;  ub2 count, i;  off_t offset;  if (lseek (fd, -22, SEEK_END) == -1)    {      fprintf (stderr, "%s: %s: can't seek file\n", progname, jarfile);      return 1;    }  if (read (fd, intbuf, 4) < 4)    {      perror (progname);      return 1;    }  /* Is there a zipfile comment? */  while (UNPACK_UB4(intbuf, 0) != 0x06054b50)    {      if (lseek (fd, -5, SEEK_CUR) == -1 ||	  read (fd, intbuf, 4) != 4)	{	  fprintf (stderr, "%s: can't find end of central directory: %s\n",		   progname, strerror (errno));	  return 1;	}    }  /* Skip disk numbers. */  if (lseek (fd, 6, SEEK_CUR) == -1)    {      perror (progname);      return 1;    }  /* Number of entries in the central directory. */  if (read (fd, intbuf, 2) != 2)    {      perror (progname);      return 1;    }  count = UNPACK_UB2(intbuf, 0);  if (lseek (fd, 4, SEEK_CUR) == -1)    {      perror (progname);      return 1;    }  /* Offset where the central directory begins. */  if (read (fd, intbuf, 4) != 4)    {      perror (progname);      return 1;    }  offset = UNPACK_UB4(intbuf, 0);  end_of_entries = offset;  if (lseek (fd, offset, SEEK_SET) != offset)    {      perror (progname);      return 1;    }  if (read (fd, header, 46) != 46)    {      fprintf (stderr, "%s: %s: unexpected end of file\n",	       progname, jarfile);      return 1;    }  for (i = 0; i < count; i++)    {      if (UNPACK_UB4(header, 0) != 0x02014b50)	{	  fprintf (stderr, "%s: can't find central directory header\n",		   progname);	  return 1;	}      ze = (struct zipentry *) malloc (sizeof (struct zipentry));      if (!ze)	{	  perror (progname);	  return 1;	}      memset (ze, 0, sizeof (struct zipentry));      ze->flags = UNPACK_UB2(header, CEN_FLAGS);      ze->mod_time = UNPACK_UB2(header, CEN_MODTIME);      ze->mod_date = UNPACK_UB2(header, CEN_MODDATE);      ze->crc = UNPACK_UB4(header, CEN_CRC);      ze->usize = UNPACK_UB4(header, CEN_USIZE);      ze->csize = UNPACK_UB4(header, CEN_CSIZE);      ze->offset = UNPACK_UB4(header, CEN_OFFSET);      ze->compressed = (header[CEN_COMP] || header[CEN_COMP+1]);      len = UNPACK_UB2(header, CEN_FNLEN);      ze->filename = (char *) malloc ((len+1) * sizeof (char));      if (!ze->filename)	{	  perror (progname);	  return 1;	}      if (read (fd, ze->filename, len) != len)	{	  fprintf (stderr, "%s: %s: unexpected end of file\n",		   progname, jarfile);	  return 1;	}      len = UNPACK_UB4(header, CEN_EFLEN);      len += UNPACK_UB4(header, CEN_COMLEN);      if (lseek (fd, len, SEEK_CUR) == -1)	{	  perror (progname);	  return 1;	}      add_entry (ze);      if (i < count - 1)	{	  if (read (fd, header, 46) != 46)	    {	      fprintf (stderr, "%s: %s: unexpected end of file\n",		       progname, jarfile);	      return 1;	    }	}    }  lseek (fd, 0, SEEK_SET);  return 0;}int make_manifest(int jfd, const char *mf_name, int updating){  time_t current_time;  int nlen;   /* length of file name */  int mod_time; /* file modification time */  struct zipentry *ze;    nlen = 9;  /* trust me on this one */  memset((file_header + 12), '\0', 16); /*clear mod time, crc, size fields*/    current_time = time(NULL);  if(current_time == (time_t)-1){    perror("time");    exit(1);  }  mod_time = unix2dostime(&current_time);    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: META-INF/ (in=0) (out=0) (stored 0%%)\n");    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, "META-INF/");  ze->filename[nlen] = '\0';      ze->offset = lseek(jfd, 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(jfd, file_header, 30);  write(jfd, "META-INF/", nlen);  /* if the user didn't specify an external manifest file... */  if(mf_name == NULL){        int mf_len = strlen(MANIFEST_STR) + strlen(VERSION) + strlen(MANIFEST_END);    char *mf;    if((mf = (char *) malloc(mf_len + 1))) {    uLong crc;    sprintf(mf, "%s%s%s", MANIFEST_STR, VERSION, MANIFEST_END);    crc = crc32(0L, Z_NULL, 0);        crc = crc32(crc, (const unsigned char *)mf, mf_len);    nlen = 20;  /* once again, trust me */    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_USIZE, mf_len);        memcpy((file_header + LOC_CSIZE), (file_header + LOC_USIZE), 4);        PACK_UB4(file_header, LOC_CRC, crc);    if(verbose)      printf("adding: META-INF/MANIFEST.MF (in=56) (out=56) (stored 0%%)\n");        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, "META-INF/MANIFEST.MF");    ze->filename[nlen] = '\0';        ze->offset = lseek(jfd, 0, SEEK_CUR);    ze->mod_time = (ub2)(mod_time & 0x0000ffff);    ze->mod_date = (ub2)((mod_time & 0xffff0000) >> 16);    ze->crc = crc;    ze->csize = mf_len;    ze->usize = ze->csize;    ze->compressed = FALSE;        add_entry(ze);        write(jfd, file_header, 30);    write(jfd, "META-INF/MANIFEST.MF", nlen);    write(jfd, mf, mf_len);    free(mf);    }    else {	printf("malloc errror\n");	exit(-1);    }  } else {    int mfd;    struct stat statbuf;    stat(mf_name, &statbuf);    if(!S_ISREG(statbuf.st_mode)){      fprintf(stderr, "Invalid manifest file specified.\n");      exit(1);    }      mfd = open(mf_name, O_RDONLY | O_BINARY);    if(mfd < 0){      fprintf(stderr, "Error opening %s.\n", mf_name);      exit(1);    }    if(add_file_to_jar(jfd, mfd, "META-INF/MANIFEST.MF", &statbuf, updating)){      perror("error writing to jar");      exit(1);    }  }  return 0;}/* Implements -C by wrapping add_to_jar.  new_dir is the directory    to switch to.   `updating', if nonzero, will indicate that we are updating an   existing file, and will need to take special care. If set, we will   also expect that the linked list of zip entries will be filled in   with the jar file's current contents. */int add_to_jar_with_dir (int fd, const char* new_dir, const char* file,		     const int updating){  int retval;  char old_dir[MAXPATHLEN];   if (getcwd(old_dir, MAXPATHLEN) == NULL) {    perror("getcwd");    return 1;  }  if (chdir(new_dir) == -1) {    perror(new_dir);    return 1;  }  retval=add_to_jar(fd, file, updating);  if (chdir(old_dir) == -1) {    perror(old_dir);    return 1;  }  return retval;}int add_to_jar (int fd, const char *file, const int updating){  struct stat statbuf;  DIR *dir;  struct dirent *de;  zipentry *ze;  zipentry *existing = NULL;  int stat_return;  /* 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(jarfile && !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);    return 1;  } 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);    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;    if (updating)      {	if ((existing = find_entry (ze->filename)) != NULL)	  {	    if (existing->usize != 0)	      {		/* XXX overwriting non-directory with directory? */		fprintf (stderr, "%s: %s: can't overwrite non-directory with directory\n",			 progname, fullname);		return 1;

⌨️ 快捷键说明

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