Esempio n. 1
0
File: coder.c Progetto: Garen/xz
memlimit_too_small(uint64_t memory_usage)
{
	message(V_ERROR, _("Memory usage limit is too low for the given "
			"filter setup."));
	message_mem_needed(V_ERROR, memory_usage);
	tuklib_exit(E_ERROR, E_ERROR, false);
}
Esempio n. 2
0
extern int
main(int argc, char **argv)
{
	tuklib_progname_init(argv);
	tuklib_gettext_init(PACKAGE, LOCALEDIR);

	parse_args(argc, argv);

#ifdef TUKLIB_DOSLIKE
	setmode(fileno(stdin), O_BINARY);
#endif

	int ret = EXIT_SUCCESS;

	// We print empty lines around the output only when reading from
	// files specified on the command line. This is due to how
	// LZMA Utils did it.
	if (optind == argc) {
		if (lzmainfo("(stdin)", stdin))
			ret = EXIT_FAILURE;
	} else {
		printf("\n");

		do {
			if (strcmp(argv[optind], "-") == 0) {
				if (lzmainfo("(stdin)", stdin))
					ret = EXIT_FAILURE;
			} else {
				FILE *f = fopen(argv[optind], "r");
				if (f == NULL) {
					ret = EXIT_FAILURE;
					fprintf(stderr, "%s: %s: %s\n",
							progname,
							argv[optind],
							strerror(errno));
					continue;
				}

				if (lzmainfo(argv[optind], f))
					ret = EXIT_FAILURE;

				printf("\n");
				fclose(f);
			}
		} while (++optind < argc);
	}

	tuklib_exit(ret, EXIT_FAILURE, true);
}
Esempio n. 3
0
help(void)
{
	printf(
_("Usage: %s [--help] [--version] [FILE]...\n"
"Show information stored in the .lzma file header"), progname);

	printf(_(
"\nWith no FILE, or when FILE is -, read standard input.\n"));
	printf("\n");

	printf(_("Report bugs to <%s> (in English or Finnish).\n"),
			PACKAGE_BUGREPORT);
	printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);

	tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, true);
}
Esempio n. 4
0
version(void)
{
	puts("lzmainfo (" PACKAGE_NAME ") " LZMA_VERSION_STRING);
	tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, true);
}
Esempio n. 5
0
static void
parse_real(args_info *args, int argc, char **argv)
{
	enum {
		OPT_X86 = INT_MIN,
		OPT_POWERPC,
		OPT_IA64,
		OPT_ARM,
		OPT_ARMTHUMB,
		OPT_SPARC,
		OPT_DELTA,
		OPT_LZMA1,
		OPT_LZMA2,

		OPT_SINGLE_STREAM,
		OPT_NO_SPARSE,
		OPT_FILES,
		OPT_FILES0,
		OPT_BLOCK_SIZE,
		OPT_MEM_COMPRESS,
		OPT_MEM_DECOMPRESS,
		OPT_NO_ADJUST,
		OPT_INFO_MEMORY,
		OPT_ROBOT,
	};

	static const char short_opts[]
			= "cC:defF:hHlkM:qQrS:tT:vVz0123456789";

	static const struct option long_opts[] = {
		// Operation mode
		{ "compress",     no_argument,       NULL,  'z' },
		{ "decompress",   no_argument,       NULL,  'd' },
		{ "uncompress",   no_argument,       NULL,  'd' },
		{ "test",         no_argument,       NULL,  't' },
		{ "list",         no_argument,       NULL,  'l' },

		// Operation modifiers
		{ "keep",         no_argument,       NULL,  'k' },
		{ "force",        no_argument,       NULL,  'f' },
		{ "stdout",       no_argument,       NULL,  'c' },
		{ "to-stdout",    no_argument,       NULL,  'c' },
		{ "single-stream", no_argument,      NULL,  OPT_SINGLE_STREAM },
		{ "no-sparse",    no_argument,       NULL,  OPT_NO_SPARSE },
		{ "suffix",       required_argument, NULL,  'S' },
		// { "recursive",      no_argument,       NULL,  'r' }, // TODO
		{ "files",        optional_argument, NULL,  OPT_FILES },
		{ "files0",       optional_argument, NULL,  OPT_FILES0 },

		// Basic compression settings
		{ "format",       required_argument, NULL,  'F' },
		{ "check",        required_argument, NULL,  'C' },
		{ "block-size",   required_argument, NULL,  OPT_BLOCK_SIZE },
		{ "memlimit-compress",   required_argument, NULL, OPT_MEM_COMPRESS },
		{ "memlimit-decompress", required_argument, NULL, OPT_MEM_DECOMPRESS },
		{ "memlimit",     required_argument, NULL,  'M' },
		{ "memory",       required_argument, NULL,  'M' }, // Old alias
		{ "no-adjust",    no_argument,       NULL,  OPT_NO_ADJUST },
		{ "threads",      required_argument, NULL,  'T' },

		{ "extreme",      no_argument,       NULL,  'e' },
		{ "fast",         no_argument,       NULL,  '0' },
		{ "best",         no_argument,       NULL,  '9' },

		// Filters
		{ "lzma1",        optional_argument, NULL,  OPT_LZMA1 },
		{ "lzma2",        optional_argument, NULL,  OPT_LZMA2 },
		{ "x86",          optional_argument, NULL,  OPT_X86 },
		{ "powerpc",      optional_argument, NULL,  OPT_POWERPC },
		{ "ia64",         optional_argument, NULL,  OPT_IA64 },
		{ "arm",          optional_argument, NULL,  OPT_ARM },
		{ "armthumb",     optional_argument, NULL,  OPT_ARMTHUMB },
		{ "sparc",        optional_argument, NULL,  OPT_SPARC },
		{ "delta",        optional_argument, NULL,  OPT_DELTA },

		// Other options
		{ "quiet",        no_argument,       NULL,  'q' },
		{ "verbose",      no_argument,       NULL,  'v' },
		{ "no-warn",      no_argument,       NULL,  'Q' },
		{ "robot",        no_argument,       NULL,  OPT_ROBOT },
		{ "info-memory",  no_argument,       NULL,  OPT_INFO_MEMORY },
		{ "help",         no_argument,       NULL,  'h' },
		{ "long-help",    no_argument,       NULL,  'H' },
		{ "version",      no_argument,       NULL,  'V' },

		{ NULL,           0,                 NULL,   0 }
	};

	int c;

	while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL))
			!= -1) {
		switch (c) {
		// Compression preset (also for decompression if --format=raw)
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			coder_set_preset(c - '0');
			break;

		// --memlimit-compress
		case OPT_MEM_COMPRESS:
			parse_memlimit("memlimit-compress",
					"memlimit-compress%", optarg,
					true, false);
			break;

		// --memlimit-decompress
		case OPT_MEM_DECOMPRESS:
			parse_memlimit("memlimit-decompress",
					"memlimit-decompress%", optarg,
					false, true);
			break;

		// --memlimit
		case 'M':
			parse_memlimit("memlimit", "memlimit%", optarg,
					true, true);
			break;

		// --suffix
		case 'S':
			suffix_set(optarg);
			break;

		case 'T':
			// The max is from src/liblzma/common/common.h.
			hardware_threads_set(str_to_uint64("threads",
					optarg, 0, 16384));
			break;

		// --version
		case 'V':
			// This doesn't return.
			message_version();

		// --stdout
		case 'c':
			opt_stdout = true;
			break;

		// --decompress
		case 'd':
			opt_mode = MODE_DECOMPRESS;
			break;

		// --extreme
		case 'e':
			coder_set_extreme();
			break;

		// --force
		case 'f':
			opt_force = true;
			break;

		// --info-memory
		case OPT_INFO_MEMORY:
			// This doesn't return.
			hardware_memlimit_show();

		// --help
		case 'h':
			// This doesn't return.
			message_help(false);

		// --long-help
		case 'H':
			// This doesn't return.
			message_help(true);

		// --list
		case 'l':
			opt_mode = MODE_LIST;
			break;

		// --keep
		case 'k':
			opt_keep_original = true;
			break;

		// --quiet
		case 'q':
			message_verbosity_decrease();
			break;

		case 'Q':
			set_exit_no_warn();
			break;

		case 't':
			opt_mode = MODE_TEST;
			break;

		// --verbose
		case 'v':
			message_verbosity_increase();
			break;

		// --robot
		case OPT_ROBOT:
			opt_robot = true;

			// This is to make sure that floating point numbers
			// always have a dot as decimal separator.
			setlocale(LC_NUMERIC, "C");
			break;

		case 'z':
			opt_mode = MODE_COMPRESS;
			break;

		// Filter setup

		case OPT_X86:
			coder_add_filter(LZMA_FILTER_X86,
					options_bcj(optarg));
			break;

		case OPT_POWERPC:
			coder_add_filter(LZMA_FILTER_POWERPC,
					options_bcj(optarg));
			break;

		case OPT_IA64:
			coder_add_filter(LZMA_FILTER_IA64,
					options_bcj(optarg));
			break;

		case OPT_ARM:
			coder_add_filter(LZMA_FILTER_ARM,
					options_bcj(optarg));
			break;

		case OPT_ARMTHUMB:
			coder_add_filter(LZMA_FILTER_ARMTHUMB,
					options_bcj(optarg));
			break;

		case OPT_SPARC:
			coder_add_filter(LZMA_FILTER_SPARC,
					options_bcj(optarg));
			break;

		case OPT_DELTA:
			coder_add_filter(LZMA_FILTER_DELTA,
					options_delta(optarg));
			break;

		case OPT_LZMA1:
			coder_add_filter(LZMA_FILTER_LZMA1,
					options_lzma(optarg));
			break;

		case OPT_LZMA2:
			coder_add_filter(LZMA_FILTER_LZMA2,
					options_lzma(optarg));
			break;

		// Other

		// --format
		case 'F': {
			// Just in case, support both "lzma" and "alone" since
			// the latter was used for forward compatibility in
			// LZMA Utils 4.32.x.
			static const struct {
				char str[8];
				enum format_type format;
			} types[] = {
				{ "auto",   FORMAT_AUTO },
				{ "xz",     FORMAT_XZ },
				{ "lzma",   FORMAT_LZMA },
				{ "alone",  FORMAT_LZMA },
				// { "gzip",   FORMAT_GZIP },
				// { "gz",     FORMAT_GZIP },
				{ "raw",    FORMAT_RAW },
			};

			size_t i = 0;
			while (strcmp(types[i].str, optarg) != 0)
				if (++i == ARRAY_SIZE(types))
					message_fatal(_("%s: Unknown file "
							"format type"),
							optarg);

			opt_format = types[i].format;
			break;
		}

		// --check
		case 'C': {
			static const struct {
				char str[8];
				lzma_check check;
			} types[] = {
				{ "none",   LZMA_CHECK_NONE },
				{ "crc32",  LZMA_CHECK_CRC32 },
				{ "crc64",  LZMA_CHECK_CRC64 },
				{ "sha256", LZMA_CHECK_SHA256 },
			};

			size_t i = 0;
			while (strcmp(types[i].str, optarg) != 0) {
				if (++i == ARRAY_SIZE(types))
					message_fatal(_("%s: Unsupported "
							"integrity "
							"check type"), optarg);
			}

			// Use a separate check in case we are using different
			// liblzma than what was used to compile us.
			if (!lzma_check_is_supported(types[i].check))
				message_fatal(_("%s: Unsupported integrity "
						"check type"), optarg);

			coder_set_check(types[i].check);
			break;
		}

		case OPT_BLOCK_SIZE:
			opt_block_size = str_to_uint64("block-size", optarg,
					0, LZMA_VLI_MAX);
			break;

		case OPT_SINGLE_STREAM:
			opt_single_stream = true;
			break;

		case OPT_NO_SPARSE:
			io_no_sparse();
			break;

		case OPT_FILES:
			args->files_delim = '\n';

		// Fall through

		case OPT_FILES0:
			if (args->files_name != NULL)
				message_fatal(_("Only one file can be "
						"specified with `--files' "
						"or `--files0'."));

			if (optarg == NULL) {
				args->files_name = (char *)stdin_filename;
				args->files_file = stdin;
			} else {
				args->files_name = optarg;
				args->files_file = fopen(optarg,
						c == OPT_FILES ? "r" : "rb");
				if (args->files_file == NULL)
					message_fatal("%s: %s", optarg,
							strerror(errno));
			}

			break;

		case OPT_NO_ADJUST:
			opt_auto_adjust = false;
			break;

		default:
			message_try_help();
			tuklib_exit(E_ERROR, E_ERROR, false);
		}
	}

	return;
}
Esempio n. 6
0
File: main.c Progetto: DrOpdRoP/xz
int
main(int argc, char **argv)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
	InitializeCriticalSection(&exit_status_cs);
#endif

	// Set up the progname variable.
	tuklib_progname_init(argv);

	// Initialize the file I/O. This makes sure that
	// stdin, stdout, and stderr are something valid.
	io_init();

	// Set up the locale and message translations.
	tuklib_gettext_init(PACKAGE, LOCALEDIR);

	// Initialize handling of error/warning/other messages.
	message_init();

	// Set hardware-dependent default values. These can be overriden
	// on the command line, thus this must be done before args_parse().
	hardware_init();

	// Parse the command line arguments and get an array of filenames.
	// This doesn't return if something is wrong with the command line
	// arguments. If there are no arguments, one filename ("-") is still
	// returned to indicate stdin.
	args_info args;
	args_parse(&args, argc, argv);

	if (opt_mode != MODE_LIST && opt_robot)
		message_fatal(_("Compression and decompression with --robot "
			"are not supported yet."));

	// Tell the message handling code how many input files there are if
	// we know it. This way the progress indicator can show it.
	if (args.files_name != NULL)
		message_set_files(0);
	else
		message_set_files(args.arg_count);

	// Refuse to write compressed data to standard output if it is
	// a terminal.
	if (opt_mode == MODE_COMPRESS) {
		if (opt_stdout || (args.arg_count == 1
				&& strcmp(args.arg_names[0], "-") == 0)) {
			if (is_tty_stdout()) {
				message_try_help();
				tuklib_exit(E_ERROR, E_ERROR, false);
			}
		}
	}

	// Set up the signal handlers. We don't need these before we
	// start the actual action and not in --list mode, so this is
	// done after parsing the command line arguments.
	//
	// It's good to keep signal handlers in normal compression and
	// decompression modes even when only writing to stdout, because
	// we might need to restore O_APPEND flag on stdout before exiting.
	// In --test mode, signal handlers aren't really needed, but let's
	// keep them there for consistency with normal decompression.
	if (opt_mode != MODE_LIST)
		signals_init();

	// coder_run() handles compression, decompression, and testing.
	// list_file() is for --list.
	void (*run)(const char *filename) = opt_mode == MODE_LIST
			 ? &list_file : &coder_run;

	// Process the files given on the command line. Note that if no names
	// were given, args_parse() gave us a fake "-" filename.
	for (size_t i = 0; i < args.arg_count && !user_abort; ++i) {
		if (strcmp("-", args.arg_names[i]) == 0) {
			// Processing from stdin to stdout. Check that we
			// aren't writing compressed data to a terminal or
			// reading it from a terminal.
			if (opt_mode == MODE_COMPRESS) {
				if (is_tty_stdout())
					continue;
			} else if (is_tty_stdin()) {
				continue;
			}

			// It doesn't make sense to compress data from stdin
			// if we are supposed to read filenames from stdin
			// too (enabled with --files or --files0).
			if (args.files_name == stdin_filename) {
				message_error(_("Cannot read data from "
						"standard input when "
						"reading filenames "
						"from standard input"));
				continue;
			}

			// Replace the "-" with a special pointer, which is
			// recognized by coder_run() and other things.
			// This way error messages get a proper filename
			// string and the code still knows that it is
			// handling the special case of stdin.
			args.arg_names[i] = (char *)stdin_filename;
		}

		// Do the actual compression or decompression.
		run(args.arg_names[i]);
	}

	// If --files or --files0 was used, process the filenames from the
	// given file or stdin. Note that here we don't consider "-" to
	// indicate stdin like we do with the command line arguments.
	if (args.files_name != NULL) {
		// read_name() checks for user_abort so we don't need to
		// check it as loop termination condition.
		while (true) {
			const char *name = read_name(&args);
			if (name == NULL)
				break;

			// read_name() doesn't return empty names.
			assert(name[0] != '\0');
			run(name);
		}

		if (args.files_name != stdin_filename)
			(void)fclose(args.files_file);
	}

	// All files have now been handled. If in --list mode, display
	// the totals before exiting. We don't have signal handlers
	// enabled in --list mode, so we don't need to check user_abort.
	if (opt_mode == MODE_LIST) {
		assert(!user_abort);
		list_totals();
	}

#ifndef NDEBUG
	coder_free();
#endif

	// If we have got a signal, raise it to kill the program instead
	// of calling tuklib_exit().
	signals_exit();

	// Make a local copy of exit_status to keep the Windows code
	// thread safe. At this point it is fine if we miss the user
	// pressing C-c and don't set the exit_status to E_ERROR on
	// Windows.
#if defined(_WIN32) && !defined(__CYGWIN__)
	EnterCriticalSection(&exit_status_cs);
#endif

	enum exit_status_type es = exit_status;

#if defined(_WIN32) && !defined(__CYGWIN__)
	LeaveCriticalSection(&exit_status_cs);
#endif

	// Suppress the exit status indicating a warning if --no-warn
	// was specified.
	if (es == E_WARNING && no_warn)
		es = E_SUCCESS;

	tuklib_exit(es, E_ERROR, message_verbosity_get() != V_SILENT);
}