jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp
author ksrini
Wed, 09 May 2012 07:28:12 -0700
changeset 12680 289f842c0175
parent 12047 320a714614e9
child 14342 8435a30053c1
permissions -rw-r--r--
7166955: (pack200) JNI_GetCreatedJavaVMs needs additional checking Reviewed-by: alanb, dholmes, ksrini Contributed-by: youdwei@linux.vnet.ibm.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2624
diff changeset
     2
 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2624
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2624
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2624
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2624
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2624
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    25
#ifdef _ALLBSD_SOURCE
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    26
#include <stdint.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    27
#define THRTYPE intptr_t
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    28
#else
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    29
#define THRTYPE int
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    30
#endif
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    31
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include <sys/types.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include <stdio.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
#include <stdarg.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
#include <errno.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
#include <limits.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
#include <time.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
#if defined(unix) && !defined(PRODUCT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
#include "pthread.h"
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    45
#define THREAD_SELF ((THRTYPE)pthread_self())
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#include "defines.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
#include "bytes.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
#include "utils.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
#include "coding.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
#include "bands.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
#include "constants.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
#include "zip.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
#include "unpack.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
int main(int argc, char **argv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    return unpacker::run(argc, argv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
// Single-threaded, implementation, not reentrant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
// Includes a weak error check against MT access.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
#ifndef THREAD_SELF
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    68
#define THREAD_SELF ((THRTYPE) 0)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
#endif
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    70
NOT_PRODUCT(static THRTYPE uThread = -1;)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
unpacker* unpacker::non_mt_current = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
unpacker* unpacker::current() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
  assert(uThread == THREAD_SELF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
  return non_mt_current;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
static void set_current_unpacker(unpacker* u) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
  unpacker::non_mt_current = u;
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 5506
diff changeset
    79
  assert(((uThread = (u == null) ? (THRTYPE) -1 : THREAD_SELF),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
          true));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
// Callback for fetching data, Unix style.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
static jlong read_input_via_stdio(unpacker* u,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
                                  void* buf, jlong minlen, jlong maxlen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
  assert(minlen <= maxlen);  // don't talk nonsense
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
  jlong numread = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
  char* bufptr = (char*) buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
  while (numread < minlen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    // read available input, up to buf.length or maxlen
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    int readlen = (1<<16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    if (readlen > (maxlen - numread))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
      readlen = (int)(maxlen - numread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    int nr = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    if (u->infileptr != null) {
1082
53833ff90c45 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents: 2
diff changeset
    96
      nr = (int)fread(bufptr, 1, readlen, u->infileptr);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
#ifndef WIN32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
      // we prefer unbuffered inputs
1082
53833ff90c45 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents: 2
diff changeset
   100
      nr = (int)read(u->infileno, bufptr, readlen);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
#else
1082
53833ff90c45 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents: 2
diff changeset
   102
      nr = (int)fread(bufptr, 1, readlen, stdin);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    if (nr <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
      if (errno != EINTR)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
      nr = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    numread += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    bufptr += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    assert(numread <= maxlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
  //fprintf(u->errstrm, "readInputFn(%d,%d) => %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
  //        (int)minlen, (int)maxlen, (int)numread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
  return numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
enum { EOF_MAGIC = 0, BAD_MAGIC = -1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
static int read_magic(unpacker* u, char peek[], int peeklen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
  assert(peeklen == 4);  // magic numbers are always 4 bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
  jlong nr = (u->read_input_fn)(u, peek, peeklen, peeklen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
  if (nr != peeklen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    return (nr == 0) ? EOF_MAGIC : BAD_MAGIC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
  int magic = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
  for (int i = 0; i < peeklen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    magic <<= 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    magic += peek[i] & 0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
  return magic;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
static void setup_gzin(unpacker* u) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
  gunzip* gzin = NEW(gunzip, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
  gzin->init(u);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
static const char* nbasename(const char* progname) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
  const char* slash = strrchr(progname, '/');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
  if (slash != null)  progname = ++slash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
  return progname;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
static const char* usage_lines[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
  "Usage:  %s [-opt... | --option=value]... x.pack[.gz] y.jar\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    "\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    "Unpacking Options\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    "  -H{h}, --deflate-hint={h}     override transmitted deflate hint: true, false, or keep (default)\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    "  -r, --remove-pack-file        remove input file after unpacking\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    "  -v, --verbose                 increase program verbosity\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    "  -q, --quiet                   set verbosity to lowest level\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    "  -l{F}, --log-file={F}         output to the given log file, or '-' for standard output (default)\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    "  -?, -h, --help                print this message\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    "  -V, --version                 print program version\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    "  -J{X}                         Java VM argument (ignored)\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
static void usage(unpacker* u, const char* progname, bool full = false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
  // WinMain does not set argv[0] to the progrname
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
  progname = (progname != null) ? nbasename(progname) : "unpack200";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
  for (int i = 0; usage_lines[i] != null; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    fprintf(u->errstrm, usage_lines[i], progname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    if (!full) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
      fprintf(u->errstrm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
              "(For more information, run %s --help .)\n", progname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
      break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
// argument parsing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
static char** init_args(int argc, char** argv, int &envargc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
  const char* env = getenv("UNPACK200_FLAGS");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
  ptrlist envargs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
  envargs.init();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
  if (env != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    char* buf = (char*) strdup(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    const char* delim = "\n\t ";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    for (char* p = strtok(buf, delim); p != null; p = strtok(null, delim)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
      envargs.add(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
  // allocate extra margin at both head and tail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
  char** argp = NEW(char*, envargs.length()+argc+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
  char** argp0 = argp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
  int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
  for (i = 0; i < envargs.length(); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    *argp++ = (char*) envargs.get(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
  for (i = 1; i < argc; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    // note: skip argv[0] (program name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    *argp++ = (char*) strdup(argv[i]);  // make a scratch copy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
  *argp = null; // sentinel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
  envargc = envargs.length();  // report this count to next_arg
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
  envargs.free();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
  return argp0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
static int strpcmp(const char* str, const char* pfx) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
  return strncmp(str, pfx, strlen(pfx));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
static const char flag_opts[] = "vqrVh?";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
static const char string_opts[] = "HlJ";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
static int next_arg(char** &argp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
  char* arg = *argp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
  if (arg == null || arg[0] != '-') { // end of option list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
  //printf("opt: %s\n", arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
  char ach = arg[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
  if (ach == '\0') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    // ++argp;  // do not pop this arg
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    return 0;  // bare "-" is stdin/stdout
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
  } else if (arg[1] == '-') {  // --foo option
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    static const char* keys[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
      "Hdeflate-hint=",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
      "vverbose",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
      "qquiet",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
      "rremove-pack-file",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
      "llog-file=",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
      "Vversion",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
      "hhelp",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
      null };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    if (arg[2] == '\0') {  // end of option list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
      ++argp;  // pop the "--"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
      return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    for (int i = 0; keys[i] != null; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
      const char* key = keys[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
      char kch = *key++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
      if (strchr(key, '=') == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        if (!strcmp(arg+2, key)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
          ++argp;  // pop option arg
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
          return kch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
      } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        if (!strpcmp(arg+2, key)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
          *argp += 2 + strlen(key);  // remove "--"+key from arg
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
          return kch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
  } else if (strchr(flag_opts, ach) != null) {  // plain option
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    if (arg[2] == '\0') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
      ++argp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
      // in-place edit of "-vxyz" to "-xyz"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
      arg += 1;  // skip original '-'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
      arg[0] = '-';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
      *argp = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    //printf("  key => %c\n", ach);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    return ach;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
  } else if (strchr(string_opts, ach) != null) {  // argument-bearing option
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    if (arg[2] == '\0') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
      if (argp[1] == null)  return -1;  // no next arg
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
      ++argp;  // leave the argument in place
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
      // in-place edit of "-Hxyz" to "xyz"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
      arg += 2;  // skip original '-H'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
      *argp = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    //printf("  key => %c\n", ach);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    return ach;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
  return -1;  // bad argument
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
static const char sccsver[] = "1.30, 07/05/05";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
// Usage:  unpackage input.pack output.jar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
int unpacker::run(int argc, char **argv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
  unpacker u;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
  u.init(read_input_via_stdio);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
  set_current_unpacker(&u);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
  jar jarout;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
  jarout.init(&u);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
  int envargc = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
  char** argbuf = init_args(argc, argv, envargc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
  char** arg0 = argbuf+envargc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
  char** argp = argbuf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
  int verbose = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
  char* logfile = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
  for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    const char* arg = (*argp == null)? "": u.saveStr(*argp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    bool isenvarg = (argp < arg0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    int ach = next_arg(argp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    bool hasoptarg = (ach != 0 && strchr(string_opts, ach) != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    if (ach == 0 && argp >= arg0)  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    if (isenvarg && argp == arg0 && hasoptarg)  ach = 0;  // don't pull from cmdline
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    switch (ach) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    case 'H':  u.set_option(UNPACK_DEFLATE_HINT,*argp++); break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    case 'v':  ++verbose; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    case 'q':  verbose = 0; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    case 'r':  u.set_option(UNPACK_REMOVE_PACKFILE,"1"); break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    case 'l':  logfile = *argp++; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    case 'J':  argp += 1; break;  // skip ignored -Jxxx parameter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    case 'V':
2602
5b394a4b6ce1 6755943: Java JAR Pack200 Decompression should enforce stricter header checks
ksrini
parents: 2
diff changeset
   309
      fprintf(u.errstrm, VERSION_STRING, nbasename(argv[0]), sccsver);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
      exit(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    case 'h':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    case '?':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
      usage(&u, argv[0], true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
      exit(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
      const char* inenv = isenvarg? " in ${UNPACK200_FLAGS}": "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
      if (hasoptarg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        fprintf(u.errstrm, "Missing option string%s: %s\n", inenv, arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
      else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        fprintf(u.errstrm, "Unrecognized argument%s: %s\n", inenv, arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
      usage(&u, argv[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
      exit(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
  if (verbose != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    u.set_option(DEBUG_VERBOSE, u.saveIntStr(verbose));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
  if (logfile != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    u.set_option(UNPACK_LOG_FILE, logfile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
  u.redirect_stdio();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
  const char* source_file      = *argp++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
  const char* destination_file = *argp++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
  if (source_file == null || destination_file == null || *argp != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    usage(&u, argv[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    exit(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
  if (verbose != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    fprintf(u.errstrm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            "Unpacking from %s to %s\n", source_file, destination_file);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
  bool& remove_source = u.remove_packfile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
  if (strcmp(source_file, "-") == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    remove_source = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    u.infileno = fileno(stdin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
  } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    u.infileptr = fopen(source_file, "rb");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    if (u.infileptr == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
       fprintf(u.errstrm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
               "Error: Could not open input file: %s\n", source_file);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
       exit(3); // Called only from the native standalone unpacker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
  if (strcmp(destination_file, "-") == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    jarout.jarfp = stdout;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    if (u.errstrm == stdout) // do not mix output
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
      u.set_option(UNPACK_LOG_FILE, LOGFILE_STDERR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
  } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    jarout.openJarFile(destination_file);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    assert(jarout.jarfp != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
  if (verbose != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    u.dump_options();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
  char peek[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
  int magic;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
  // check for GZIP input
1082
53833ff90c45 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents: 2
diff changeset
   379
  magic = read_magic(&u, peek, (int)sizeof(peek));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
  if ((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    // Oops; must slap an input filter on this data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    setup_gzin(&u);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    u.gzin->start(magic);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    if (!u.aborting()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
      u.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
  } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    u.start(peek, sizeof(peek));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
  // Note:  The checks to u.aborting() are necessary to gracefully
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
  // terminate processing when the first segment throws an error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
  for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    if (u.aborting())  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    // Each trip through this loop unpacks one segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    // and then resets the unpacker.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
    for (unpacker::file* filep; (filep = u.get_next_file()) != null; ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
      if (u.aborting())  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
      u.write_file_to_jar(filep);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    if (u.aborting())  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    // Peek ahead for more data.
1082
53833ff90c45 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents: 2
diff changeset
   406
    magic = read_magic(&u, peek, (int)sizeof(peek));
53833ff90c45 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents: 2
diff changeset
   407
    if (magic != (int)JAVA_PACKAGE_MAGIC) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
      if (magic != EOF_MAGIC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        u.abort("garbage after end of pack archive");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
      break;   // all done
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    // Release all storage from parsing the old segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    u.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    // Restart, beginning with the peek-ahead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    u.start(peek, sizeof(peek));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
  int status = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
  if (u.aborting()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    fprintf(u.errstrm, "Error: %s\n", u.get_abort_message());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    status = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
  if (u.infileptr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    fclose(u.infileptr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    u.infileptr = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
  if (!u.aborting() && remove_source)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    remove(source_file);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
  if (verbose != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    fprintf(u.errstrm, "unpacker completed with status=%d\n", status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
  u.finish();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
  u.free();  // tidy up malloc blocks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
  set_current_unpacker(null);  // clean up global pointer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
  return status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
}