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

📄 main.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* main.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 Laszlo Molnar   All Rights Reserved.   UPX and the UCL library are free software; you can redistribute them   and/or modify them 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; see the file COPYING.   If not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Markus F.X.J. Oberhumer              Laszlo Molnar   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#include "conf.h"#include "mygetopt.h"#include "file.h"#include "packer.h"#include "p_elf.h"#if 1 && defined(__DJGPP__)#include <crt0.h>int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;#endif/*************************************************************************// options**************************************************************************/void options_t::reset(){    options_t *o = this;    memset(o, 0, sizeof(*o));    o->crp.reset();    o->cmd = CMD_NONE;    o->method = M_NONE;    o->level = -1;    o->filter = FT_NONE;    o->backup = -1;    o->overlay = -1;    o->preserve_mode = true;    o->preserve_ownership = true;    o->preserve_timestamp = true;    o->console = CON_FILE;#if defined(__DJGPP__)    o->console = CON_INIT;#elif defined(USE_SCREEN_WIN32)    o->console = CON_INIT;#elif 1 && defined(__linux__)    o->console = CON_INIT;#endif    o->verbose = 2;    o->win32_pe.compress_exports = 1;    o->win32_pe.compress_icons = 2;    o->win32_pe.compress_resources = -1;    for (unsigned i = 0; i < TABLESIZE(o->win32_pe.compress_rt); i++)        o->win32_pe.compress_rt[i] = -1;    o->win32_pe.compress_rt[24] = false;    // 24 == RT_MANIFEST    o->win32_pe.strip_relocs = -1;    o->win32_pe.keep_resource = "";}static options_t global_options;options_t *opt = &global_options;static int done_output_name = 0;static int done_script_name = 0;const char *argv0 = "";const char *progname = "";static int num_files = -1;static int exit_code = EXIT_OK;/*************************************************************************// exit handlers**************************************************************************/#if defined(__GNUC__)static void do_exit(void) __attribute__((__noreturn__));#endifstatic void do_exit(void){    static bool in_exit = false;    if (in_exit)        exit(exit_code);    in_exit = true;    fflush(con_term);    fflush(stderr);    exit(exit_code);}#define EXIT_FATAL  3static bool set_eec(int ec, int *eec){    if (ec == EXIT_FATAL)    {        *eec = EXIT_ERROR;        return 1;    }    else if (ec < 0 || ec == EXIT_ERROR)    {        *eec = EXIT_ERROR;    }    else if (ec == EXIT_WARN)    {        if (!opt->ignorewarn)            if (*eec == EXIT_OK)                *eec = ec;    }    else if (ec == EXIT_OK)    {        /* do nothing */    }    else    {        assert(0);    }    return 0;}bool set_ec(int ec){    return set_eec(ec,&exit_code);}void e_exit(int ec){    (void) set_ec(ec);    do_exit();}void e_usage(void){    show_usage();    e_exit(EXIT_USAGE);}void e_memory(void){    show_head();    fflush(con_term);    fprintf(stderr,"%s: out of memory\n", argv0);    e_exit(EXIT_MEMORY);}static void e_method(int m, int l){    fflush(con_term);    fprintf(stderr,"%s: illegal method option -- %d/%d\n", argv0, m, l);    e_usage();}static void e_optarg(const char *n){    fflush(con_term);    fprintf(stderr,"%s: invalid argument in option '%s'\n", argv0, n);    e_exit(EXIT_USAGE);}static void e_optval(const char *n){    fflush(con_term);    fprintf(stderr,"%s: invalid value for option '%s'\n", argv0, n);    e_exit(EXIT_USAGE);}#if defined(OPTIONS_VAR)void e_envopt(const char *n){    fflush(con_term);    if (n)        fprintf(stderr,"%s: invalid string '%s' in environment variable '%s'\n",                        argv0, n, OPTIONS_VAR);    else        fprintf(stderr,"%s: illegal option in environment variable '%s'\n",                        argv0, OPTIONS_VAR);    e_exit(EXIT_USAGE);}#endif /* defined(OPTIONS_VAR) */void __acc_cdecl_sighandler e_sighandler(int signum){    UNUSED(signum);    e_exit(EXIT_FATAL);}/*************************************************************************// check options**************************************************************************/void check_not_both(bool e1, bool e2, const char *c1, const char *c2){    if (e1 && e2)    {        fprintf(stderr,"%s: ",argv0);        fprintf(stderr,"cannot use both '%s' and '%s'\n", c1, c2);        e_usage();    }}void check_options(int i, int argc){    assert(i <= argc);    if (opt->cmd != CMD_COMPRESS)    {        // invalidate compression options        opt->method = 0;        opt->level = 0;        opt->exact = 0;        opt->small = 0;        opt->crp.reset();    }    // set default overlay action    if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))        opt->overlay = opt->COPY_OVERLAY;    else if (opt->overlay < 0)        opt->overlay = opt->COPY_OVERLAY;    check_not_both(opt->exact, opt->overlay == opt->STRIP_OVERLAY, "--exact", "--overlay=strip");    // set default backup option    if (opt->backup < 0)        opt->backup = 0;    if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))        opt->backup = 1;    check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");    if (opt->to_stdout && opt->cmd == CMD_COMPRESS)    {        fprintf(stderr,"%s: cannot use '--stdout' when compressing\n", argv0);        e_usage();    }    if (opt->to_stdout || opt->output_name)    {        if (i + 1 != argc)        {            fprintf(stderr,"%s: need exactly one argument when using '%s'\n",                    argv0, opt->to_stdout ? "--stdout" : "-o");            e_usage();        }    }}/*************************************************************************// misc**************************************************************************/void e_help(void){    show_help();    e_exit(EXIT_USAGE);}static void set_term(FILE *f){    if (f)        con_term = f;    else        con_term = acc_isatty(STDIN_FILENO) ? stderr : stdout;}static void set_cmd(int cmd){    if (cmd > opt->cmd)        opt->cmd = cmd;}static bool set_method(int m, int l){    if (m > 0)    {        if (!Packer::isValidCompressionMethod(m))            return false;#if 1        // something like "--brute --lzma" should not disable "--brute"        if (!opt->all_methods)#endif        {            opt->method = m;            opt->all_methods = false;        }    }    if (l > 0)        opt->level = l;    set_cmd(CMD_COMPRESS);    return true;}static void set_output_name(const char *n, bool allow_m){#if 1    if (done_output_name > 0)    {        fprintf(stderr,"%s: option '-o' more than once given\n",argv0);        e_usage();    }#endif    if (!n || !n[0] || (!allow_m && n[0] == '-'))    {        fprintf(stderr,"%s: missing output name\n",argv0);        e_usage();    }    if (strlen(n) >= ACC_FN_PATH_MAX - 4)    {        fprintf(stderr,"%s: output name too long\n",argv0);        e_usage();    }    opt->output_name = n;    done_output_name++;}static void set_script_name(const char *n, bool allow_m){#if 1    if (done_script_name > 0)    {        fprintf(stderr,"%s: option '--script' more than once given\n",argv0);        e_usage();    }#endif    if (!n || !n[0] || (!allow_m && n[0] == '-'))    {        fprintf(stderr,"%s: missing script name\n",argv0);        e_usage();    }    if (strlen(n) >= (size_t)opt->o_unix.SCRIPT_MAX - 3)    {        fprintf(stderr,"%s: script name too long\n",argv0);        e_usage();    }    opt->o_unix.script_name = n;    done_script_name++;}/*************************************************************************// get options**************************************************************************/staticchar* prepare_shortopts(char *buf, const char *n,                        const struct mfx_option *longopts){    char *o = buf;    for ( ; n && *n; n++)        if (*n != ' ')            *o++ = *n;    *o = 0;    for ( ; longopts && longopts->name; longopts++)    {        int v = longopts->val;#if !defined(NDEBUG)        assert(longopts->name[0] != '\0');        assert(longopts->name[0] != '-');        if (longopts->has_arg & 0x20)            assert((longopts->has_arg & 0xf) == 1);#endif#if 0        static char vopts[1024];        if (v > 0 && v < 1024)        {            if (vopts[v] && strchr(buf,v) == NULL)                printf("warning: duplicate option %d ('%c')!\n", v, v & 127);            vopts[v] = 1;        }#endif        if (v > 0 && v < 256 && strchr(buf,v) == NULL)        {            *o++ = (char) v;            if ((longopts->has_arg & 0xf) >= 1)                *o++ = ':';            if ((longopts->has_arg & 0xf) >= 2)                *o++ = ':';            *o = 0;        }        if (longopts->has_arg & 0x20)            assert((longopts->has_arg & 0xf) == 1);    }    return buf;}template <class T>int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal){    const char *p = mfx_optarg;    char *endptr;    int r = 0;    long n;    T v;    if (!p || !p[0])        { r = -1; goto error; }    // avoid interpretation as octal value    while (p[0] == '0' && isdigit(p[1]))        p++;    n = strtol(p, &endptr, 0);    if (*endptr != '\0')        { r = -2; goto error; }    v = (T) n;    if (v < min_value)        { r = -3; goto error; }    if (v > max_value)        { r = -4; goto error; }    *var = v;    goto done;error:    if (arg_fatal != NULL)        e_optval(arg_fatal);done:    return r;}#if 1 && (ACC_CC_GNUC >= 0x030300)template <class T, T default_value, T min_value, T max_value>int getoptvar(OptVar<T,default_value,min_value,max_value> *var, const char *arg_fatal){    T v = default_value;    int r = getoptvar(&v, min_value, max_value, arg_fatal);    if (r == 0)        *var = v;    return r;}#elsetemplate <class T>int getoptvar(T *var, const char *arg_fatal){    typename T::Type v = T::default_value_c;    int r = getoptvar(&v, T::min_value_c, T::max_value_c, arg_fatal);    if (r == 0)        *var = v;    return r;}#endifstatic int do_option(int optc, const char *arg){    int i = 0;    switch (optc)    {#if 0    // FIXME: to_stdout doesn't work because of console code mess    //case 'c':    case 517:        opt->to_stdout = true;        break;#endif    case 'd':        set_cmd(CMD_DECOMPRESS);        break;    case 'D':        opt->debug.debug_level++;        break;    case 'f':        opt->force++;        break;    case 909:        set_cmd(CMD_FILEINFO);        break;    case 'h':    case 'H':    case '?':        set_cmd(CMD_HELP);

⌨️ 快捷键说明

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