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

📄 jartool.c

📁 jar文件处理原程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  jartool.c - main functions for fastjar utility  Copyright (C) 1999  Bryan Burns    This program is free software; you can redistribute it and/or  modify it under the terms of the GNU General Public License  as published by the Free Software Foundation; either version 2  of the License, or (at your option) any later version.    This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.    You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*//* $Id: jartool.c,v 1.2 1999/12/06 07:38:28 toast Exp $   $Log: jartool.c,v $   Revision 1.2  1999/12/06 07:38:28  toast   fixed recursive archiving bug   Revision 1.1.1.1  1999/12/06 03:09:34  toast   initial checkin..   Revision 1.22  1999/10/12 19:45:13  burnsbr   adding patch to fix compat problem   Revision 1.21  1999/05/10 09:15:49  burnsbr   fixed manifest file version info   Revision 1.20  1999/05/10 08:53:16  burnsbr   *** empty log message ***   Revision 1.19  1999/05/10 08:30:39  burnsbr   added extract / listing code   Revision 1.18  1999/04/28 04:24:29  burnsbr   updated version   Revision 1.17  1999/04/28 04:21:23  burnsbr   added support for -C dir-changing flag.. Updated total compression display   Revision 1.16  1999/04/27 10:28:22  burnsbr   updated version string   Revision 1.15  1999/04/27 10:04:06  burnsbr   configure support   Revision 1.14  1999/04/27 08:56:14  burnsbr   added -V flag, better error messages   Revision 1.13  1999/04/26 02:35:21  burnsbr   changed all sorts of stuff.. compression now works 100%   Revision 1.12  1999/04/23 12:00:45  burnsbr   90% done with compression code   Revision 1.11  1999/04/22 04:12:57  burnsbr   finished first round of Manifest file support..   might need to do more, digest etc..   Revision 1.10  1999/04/22 02:35:23  burnsbr   added more manifest support, about 75% done now.  Replaced all the   redundant shifts and bit-logic with a macro or two, making the code   easier to read.   Revision 1.9  1999/04/21 09:55:16  burnsbr   pulled out printfs   Revision 1.8  1999/04/21 02:58:01  burnsbr   started manifest code   Revision 1.7  1999/04/20 23:15:28  burnsbr   added patch sent by John Bley <jbb6@acpub.duke.edu>   Revision 1.6  1999/04/20 08:56:02  burnsbr   added GPL comment   Revision 1.5  1999/04/20 08:16:09  burnsbr   fixed verbose flag, did some optimization   Revision 1.4  1999/04/20 05:09:59  burnsbr   added rcsid variable   Revision 1.3  1999/04/20 05:08:54  burnsbr   fixed Log statement*/#include "config.h"#include <zlib.h>#ifdef STDC_HEADERS#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <stdio.h>#include <sys/stat.h>#include <sys/types.h>#ifdef HAVE_DIRENT_H#include <dirent.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#include <string.h>#include <errno.h>#ifdef TM_IN_SYS_TIME#include <sys/time.h>#else#include <time.h>#endif#include "jartool.h"#include "zipfile.h"#include "dostime.h"#include "pushback.h"#include "compress.h"static char version_string[] = VERSION;static char rcsid[] = "$Id: jartool.c,v 1.2 1999/12/06 07:38:28 toast Exp $";extern int errno;void usage(char*);void add_entry(struct zipentry *);void init_headers();int consume(pb_file *, int);int list_jar(int, char**, int);int extract_jar(int, char**, int);int add_file_to_jar(int, int, char*, struct stat*);int add_to_jar(int, char*, char*);int create_central_header(int);int make_manifest(int, char*);/* global variables */ub1 file_header[30];ub1 data_descriptor[16];int do_compress;int seekable;int verbose;char jarfile[256];zipentry *ziplist; /* linked list of entries */zipentry *ziptail; /* tail of the linked list */int number_of_entries; /* number of entries in the linked list */int main(int argc, char **argv){  char mfile[256];    int action = ACTION_NONE;  int manifest = TRUE;  int manifest_file = FALSE;  int file = FALSE;  int file_first = FALSE;    int i, j;  int jarfd = -1;    do_compress = TRUE;  verbose = FALSE;    ziplist = NULL;    number_of_entries = 0;    if(argc < 2)    usage(argv[0]);    j = strlen(argv[1]);    for(i = 0; i < j; i++){    switch(argv[1][i]){    case 'c':      action = ACTION_CREATE;      break;    case 't':      action = ACTION_LIST;      break;    case 'x':      action = ACTION_EXTRACT;      break;    case 'u':      action = ACTION_UPDATE;      break;    case 'v':      verbose = TRUE;      break;    case 'V':      printf("%s\n", version_string);      exit(0);    case 'f':      file = TRUE;      if(!manifest_file)        file_first = TRUE;      else        file_first = FALSE;      break;    case 'm':      manifest_file = TRUE;      break;    case '0':      do_compress = FALSE;      break;    case 'M':      manifest = FALSE;      break;    case '-':      break;    default:      fprintf(stderr, "Illegal option: %c\n", argv[1][i]);      usage(argv[0]);    }  }  if(action == ACTION_NONE){    fprintf(stderr, "One of options -{ctxu} must be specified.\n");    usage(argv[0]);  }  i = 2;  /* get the jarfile and manifest file (if any) */  if(file && file_first){    if(i >= argc)      usage(argv[0]);    strncpy(jarfile, argv[i++], 256);  }  if(manifest_file){    if(i >= argc)      usage(argv[0]);    strncpy(mfile, argv[i++], 256);  }  if(file && !file_first){    if(i >= argc)      usage(argv[0]);    strncpy(jarfile, argv[i++], 256);  }  /* create the jarfile */  if(action == ACTION_CREATE){    if(file){      jarfd = creat(jarfile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);            if(jarfd < 0){        fprintf(stderr, "Error opening %s for writing!\n", jarfile);        perror(jarfile);        exit(1);      }            /* We assume that the file is seekable */      seekable = TRUE;          } else {            jarfd = STDOUT_FILENO;  /* jarfd is stdout otherwise */            /* standard out is not seekable */      seekable = FALSE;            /* don't want our output to be part of the jar file.. figured this one         out the hard way.. =P */      verbose = FALSE;    }  } else if(action == ACTION_LIST || action == ACTION_EXTRACT){    if(file){      jarfd = open(jarfile, O_RDONLY);      if(jarfd < 0){        fprintf(stderr, "Error opening %s for reading!\n", jarfile);        perror(jarfile);        exit(1);      }      seekable = TRUE;    } else {      jarfd = STDIN_FILENO; /* jarfd is standard in */      /* we assume that the stream isn't seekable for safety */      seekable = FALSE;    }  }  if(action == ACTION_CREATE || action == ACTION_UPDATE){    init_headers();        if(do_compress)      init_compression();      /* Add the META-INF/ directory and the manifest */    if(manifest && manifest_file)      make_manifest(jarfd, mfile);    else if(manifest)      make_manifest(jarfd, NULL);        /* now we add the files to the archive */    for(; i < argc; i++){  /* i already is in the right location*/            if(!strcmp(argv[i], "-C")){        if(add_to_jar(jarfd, argv[i+1], argv[i+2])){          printf("Error adding %s to jar archive!\n", argv[i]);          exit(1);        }        i += 2;      } else {        if(add_to_jar(jarfd, NULL, argv[i])){          printf("Error adding %s to jar archive!\n", argv[i]);          exit(1);        }      }    }    /* de-initialize the compression DS */    if(do_compress)      end_compression();        create_central_header(jarfd);        if (close(jarfd) != 0) {      fprintf(stderr, "Error closing jar archive!\n");    }  } else if(action == ACTION_LIST){    list_jar(jarfd, &argv[i], (argc - i));  } else if(action == ACTION_EXTRACT){    extract_jar(jarfd, &argv[i], (argc - i));  }    exit(0);}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++;}int make_manifest(int jfd, char *mf_name){  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 = 37 + strlen(VERSION);    uLong crc;    char mf[mf_len + 1];    sprintf(mf, "Manifest-Version: 1.0\nCreated-By: %s\n\n", VERSION);    crc = crc32(0L, Z_NULL, 0);        crc = crc32(crc, 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);      } 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);    if(mfd < 0){      fprintf(stderr, "Error opening %s.\n", mf_name);

⌨️ 快捷键说明

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