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

📄 jartool.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 4 页
字号:
        }else {          fprintf(stderr, "Hmmm.. %s exists but isn't a directory!\n",                  tmp_buff);          exit(1);        }        #ifdef DEBUG            printf("Making directory..\n");#endif        if(mkdir(tmp_buff, 0755) < 0){          perror("mkdir");          exit(1);        }        if(verbose && handle)          printf("%10s: %s/\n", "created", tmp_buff);      }      /* only a directory */      if(strlen((const char *)start) == 0)        dir = TRUE;#ifdef DEBUG          printf("Leftovers are \"%s\" (%d)\n", start, strlen((const char *)start));#endif      /* If the entry was just a directory, don't write to file, etc */      if(strlen((const char *)start) == 0)        f_fd = -1;      free(tmp_buff);    }    if(f_fd != -1 && handle){      f_fd = open((const char *)filename,                  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);      if(f_fd < 0){        fprintf(stderr, "Error extracting JAR archive!\n");        perror((const char *)filename);        exit(1);      }    }    if(method != 8 && flags & 0x0008){      fprintf(stderr, "Error in JAR file! (not compressed but data desc.)\n");      exit(1);    }    if (eflen > 0)      consume(&pbf, eflen);    if(method == 8 || flags & 0x0008){            inflate_file(&pbf, f_fd, &ze);    } else {#ifdef DEBUG          printf("writing stored data.. (%d bytes)\n", csize);#endif      out_a = 0;      in_a = csize;      ze.crc = crc32(ze.crc, NULL, 0); /* initialize the crc */      while(out_a < (int)csize){        rdamt = (in_a > RDSZ ? RDSZ : in_a);        if(pb_read(&pbf, rd_buff, rdamt) != rdamt){          perror("read");          exit(1);        }                ze.crc = crc32(ze.crc, (Bytef*)rd_buff, rdamt);        if(f_fd >= 0)          write(f_fd, rd_buff, rdamt);        out_a += rdamt;        in_a -= rdamt;#ifdef DEBUG            printf("%d bytes written\n", out_a);#endif      }    }    /* if there is a data descriptor left, compare the CRC */    if(flags & 0x0008){      if(pb_read(&pbf, scratch, 16) != 16){        perror("read");        exit(1);      }      signature = UNPACK_UB4(scratch, 0);      if(signature != 0x08074b50){        fprintf(stderr, "Error! Missing data descriptor!\n");        exit(1);      }      crc = UNPACK_UB4(scratch, 4);    }    if(crc != ze.crc){      fprintf(stderr, "Error! CRCs do not match! Got %x, expected %x\n",              ze.crc, crc);      exit(1);    }    close(f_fd);    if(verbose && dir == FALSE && handle)      printf("%10s: %s\n",             (method == 8 ? "inflated" : "extracted"),             filename);  }  return 0;}int list_jar(int fd, char **files, int file_num){  ub4 signature;  ub4 csize;  ub4 usize;  ub4 mdate;  ub4 tmp;  ub2 fnlen;  ub2 eflen;  ub2 clen;  ub2 flags;  ub2 method;  ub2 cen_size;  ub1 *filename = NULL;  ub1 scratch[16];  ub1 cen_header[46];  int filename_len = 0;  off_t size;  int i, j;  time_t tdate;  struct tm *s_tm;  char ascii_date[31];  zipentry ze;#ifdef DEBUG  printf("Listing jar file, looking for %d files\n", file_num);#endif  /* This should be the start of the central-header-end section */  if(seekable){    if(lseek(fd, -22, SEEK_END) == (off_t)-1){      perror("lseek");      exit(1);    }        if(read(fd, &tmp, sizeof(ub4)) != 4){      perror("read");      exit(1);    }#ifdef WORDS_BIGENDIAN    tmp = L2BI(tmp);#endif    if(tmp != 0x06054b50){      fprintf(stderr, "Error in JAR file format. zip-style comment?\n");      exit(1);    }    if(lseek(fd, 6, SEEK_CUR) == (off_t)-1){      perror("lseek");      exit(1);    }      if(read(fd, &cen_size, 2) != 2){      perror("read");      exit(1);    }#ifdef WORDS_BIGENDIAN    cen_size = L2BS(cen_size);#endif    /*   printf("%hu entries in central header\n", cen_size); */    if(lseek(fd, 4, SEEK_CUR) == (off_t)-1){      perror("lseek");      exit(1);    }    if(read(fd, &tmp, 4) != 4){      perror("read");      exit(1);    }#ifdef WORDS_BIGENDIAN    tmp = L2BI(tmp);#endif    /*   printf("Central header offset = %d\n", tmp); */    if(lseek(fd, tmp, SEEK_SET) != (int)tmp){      perror("lseek");      exit(1);    }    /* Loop through the entries in the central header */    for(i = 0; i < cen_size; i++){          if(read(fd, &cen_header, 46) != 46){        perror("read");        exit(1);      }      signature = UNPACK_UB4(cen_header, 0);      if(signature != 0x02014b50){        fprintf(stderr, "Error in JAR file! Cannot locate central header!\n");        exit(1);      }      usize = UNPACK_UB4(cen_header, CEN_USIZE);      fnlen = UNPACK_UB2(cen_header, CEN_FNLEN);      eflen = UNPACK_UB2(cen_header, CEN_EFLEN);      clen = UNPACK_UB2(cen_header, CEN_COMLEN);      /* If we're providing verbose output, we need to make an ASCII       * formatted version of the date. */      if(verbose){        mdate = UNPACK_UB4(cen_header, CEN_MODTIME);        tdate = dos2unixtime(mdate);        s_tm = localtime(&tdate);        strftime(ascii_date, 30, "%a %b %d %H:%M:%S %Z %Y", s_tm);        ascii_date[30] = '\0';      }      if(filename_len < fnlen + 1){        if(filename != NULL)          free(filename);              filename = malloc(sizeof(ub1) * (fnlen + 1));        filename_len = fnlen + 1;      }          if(read(fd, filename, fnlen) != fnlen){        perror("read");        exit(1);      }      filename[fnlen] = '\0';          /* if the user specified a list of files on the command line,         we'll only display those, otherwise we'll display everything */      if(file_num > 0){        for(j = 0; j < file_num; j++)          if(strcmp(files[j], (const char *)filename) == 0){            if(verbose)              printf("%6d %s %s\n", usize, ascii_date, filename);            else              printf("%s\n", filename);            break;          }      } else {        if(verbose)          printf("%6d %s %s\n", usize, ascii_date, filename);        else          printf("%s\n", filename);      }                        size = eflen + clen;      if(size > 0){        if(lseek(fd, size, SEEK_CUR) == (off_t)-1){          perror("lseek");          exit(1);        }      }    }  } else {    /* the file isn't seekable.. evil! */    pb_file pbf;    pb_init(&pbf, fd);    init_inflation();    for(;;){      if(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){#ifdef DEBUG        printf("Ick! %#x\n", signature);#endif        break;      }            if(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);#endif            method = UNPACK_UB2(file_header, LOC_COMP);#ifdef DEBUG      printf("Compression method is %#hx\n", method);#endif      flags = UNPACK_UB2(file_header, LOC_EXTRA);#ifdef DEBUG      printf("Flags are %#hx\n", flags);#endif            usize = UNPACK_UB4(file_header, LOC_USIZE);      /* If we're providing verbose output, we need to make an ASCII       * formatted version of the date. */      if(verbose){        mdate = UNPACK_UB4(file_header, LOC_MODTIME);        tdate = dos2unixtime(mdate);        s_tm = localtime(&tdate);        strftime(ascii_date, 30, "%a %b %d %H:%M:%S %Z %Y", s_tm);      }      if(filename_len < fnlen + 1){        if(filename != NULL)          free(filename);                filename = malloc(sizeof(ub1) * (fnlen + 1));        ascii_date[30] = '\0';        filename_len = fnlen + 1;      }            pb_read(&pbf, filename, fnlen);      filename[fnlen] = '\0';            /* the header is at the end.  In a JAR file, this means that the data         happens to be compressed.  We have no choice but to inflate the         data */      if(flags & 0x0008){        size = eflen;        if(size > 0)          consume(&pbf, size);                if(method == 8){#ifdef DEBUG          printf("inflating %s\n", filename);#endif          inflate_file(&pbf, -1, &ze);          usize = ze.usize;        } else           printf("We're shit outta luck!\n");                } else {        size = csize + (eflen > 0 ? eflen : 0);        #ifdef DEBUG        printf("Skipping %ld bytes\n", (long)size);#endif        consume(&pbf, size);      }      /* print out the listing */      if(file_num > 0){        for(j = 0; j < file_num; j++)          if(strcmp(files[j], (const char *)filename) == 0){            if(verbose)              printf("%6d %s %s\n", usize, ascii_date, filename);            else              printf("%s\n", filename);            break;          }      } else {        if(verbose)          printf("%6d %s %s\n", usize, ascii_date, filename);        else          printf("%s\n", filename);      }            }  }  return 0;}int consume(pb_file *pbf, int amt){  int tc = 0; /* total amount consumed */  ub1 buff[RDSZ];  int rdamt;#ifdef DEBUG  printf("Consuming %d bytes\n", amt);#endif  if (seekable){    if (amt <= (int)pbf->buff_amt)      pb_read(pbf, buff, amt);    else {      lseek(pbf->fd, amt - pbf->buff_amt, SEEK_CUR);      pb_read(pbf, buff, pbf->buff_amt); /* clear pbf */    }  } else  while(tc < amt){    rdamt = pb_read(pbf, buff, ((amt - tc) < RDSZ ? (amt - tc) : RDSZ));#ifdef DEBUG    printf("got %d bytes\n", rdamt);#endif    tc += rdamt;  }#ifdef DEBUG  printf("%d bytes consumed\n", amt);#endif  return 0;}void usage(const char *filename){  fprintf(stderr, "Try `%s --help' for more information.\n", filename);  exit (1);}void version (){  printf("jar (%s) %s\n\n", PACKAGE, VERSION);  printf("Copyright 1999, 2000, 2001  Bryan Burns\n");  printf("Copyright 2002, 2004 Free Software Foundation\n");  printf("\This is free software; see the source for copying conditions.  There is NO\n\warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");  exit (0);}void help(const char *filename){  printf("\Usage: %s {ctxuV}[vfm0ME@] [jar-file] [manifest-file] [-C dir] files ...\n\\n\Store many files together in a single `jar' file.\n\\n\  -c              create new archive\n\  -t              list table of contents for archive\n\  -x              extract named (or all) files from archive\n\  -u              update existing archive\n\", filename);  printf("\n\  -@              read names from stdin\n\  -0              store only; use no ZIP compression\n\  -C DIR FILE     change to the specified directory and include\n\                  the following file\n\  -E              don't include the files found in a directory\n\  -f FILE         specify archive file name\n\  --help          print this help, then exit\n\  -m FILE         include manifest information from specified manifest file\n\  -M              Do not create a manifest file for the entries\n\  -v              generate verbose output on standard output\n\  -V, --version   display version information\n\");  printf("\n\If any file is a directory then it is processed recursively.\n\The manifest file name and the archive file name needs to be specified\n\in the same order the 'm' and 'f' flags are specified.\n\\n\Example 1: to archive two class files into an archive called classes.jar: \n\     jar cvf classes.jar Foo.class Bar.class \n\Example 2: use an existing manifest file 'mymanifest' and archive all the\n\     files in the foo/ directory into 'classes.jar': \n\     jar cvfm classes.jar mymanifest -C foo/ .\n\");  exit(0);}static char *jt_strdup(s)     char *s;{  char *result = (char*)malloc(strlen(s) + 1);  if (result == (char*)0)    return (char*)0;  strcpy(result, s);  return result;}/* Convert "tar-style" first argument to a form expected by getopt.   This idea and the code comes from GNU tar.  This can allocate a new   argument vector.  This might leak some memory, but we don't care.  */static voidexpand_options (int *argcp, char ***argvp){  int argc = *argcp;  char **argv = *argvp;  /* Accept arguments with a leading "-" (eg "-cvf"), but don't do expansion      if a long argument (like "--help") is detected. */  if (argc > 1 && argv[1][1] != '-')    {      char buf[3];      char **new_argv;      int new_argc;      int args_to_expand;      char *p;      char **in, **out;      buf[0] = '-';      buf[2] = '\0';      args_to_expand = strlen (argv[1]);      if (argv[1][0] == '-')        --args_to_expand;              new_argc = argc - 1 + args_to_expand;      new_argv = (char **) malloc (new_argc * sizeof (char *));      in = argv;      out = new_argv;      *out++ = *in++;      p = *in++;      if (*p == '-')        p++;      while (*p != '\0')	{	  char *opt;	  buf[1] = *p;	  *out++ = jt_strdup (buf);	  /* If the option takes an argument, move the next argument	     to just after this option.  */	  opt = strchr (OPTION_STRING, *p);	  if (opt && opt[1] == ':')	    {	      if (in < argv + argc)		*out++ = *in++;	      else		{		  fprintf(stderr, "%s: option `%s' requires an argument.\n",			  argv[0], buf);		  usage(argv[0]);		}	    }	  ++p;	}      /* Copy remaining options.  */      while (in < argv + argc)	*out++ = *in++;      *argcp = new_argc;      *argvp = new_argv;    }}

⌨️ 快捷键说明

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