mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 06:45:45 -04:00
Initial community commit
This commit is contained in:
23
Src/external_dependencies/openmpt-trunk/include/lhasa/src/Makefile.am
vendored
Normal file
23
Src/external_dependencies/openmpt-trunk/include/lhasa/src/Makefile.am
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
bin_PROGRAMS=lha
|
||||
check_PROGRAMS=test-lha
|
||||
|
||||
SOURCE_FILES= \
|
||||
main.c \
|
||||
options.h \
|
||||
filter.c filter.h \
|
||||
list.c list.h \
|
||||
extract.c extract.h \
|
||||
safe.c safe.h
|
||||
|
||||
lha_SOURCES=$(SOURCE_FILES)
|
||||
lha_CFLAGS=$(MAIN_CFLAGS) -I$(top_builddir)/lib/public -I$(top_builddir)
|
||||
lha_LDADD=$(top_builddir)/lib/liblhasa.la
|
||||
|
||||
test_lha_SOURCES=$(SOURCE_FILES)
|
||||
test_lha_CFLAGS=$(TEST_CFLAGS) -I$(top_builddir)/lib/public -I$(top_builddir)
|
||||
test_lha_LDADD=$(top_builddir)/lib/liblhasatest.a
|
||||
|
||||
clean-local:
|
||||
rm -f *.gcno *.gcda *.c.gcov
|
||||
|
76
Src/external_dependencies/openmpt-trunk/include/lhasa/src/args.txt
vendored
Normal file
76
Src/external_dependencies/openmpt-trunk/include/lhasa/src/args.txt
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
Notes on command line arguments:
|
||||
|
||||
Mode - must be the first character of the first argument. Leading '-'
|
||||
is ignored:
|
||||
|
||||
e/x - Extract
|
||||
l/v - List (normal / verbose mode)
|
||||
t - Test CRC
|
||||
p - Print files to STDOUT
|
||||
|
||||
Options - flags following the mode character. Options are accepted
|
||||
even if they are inappropriate for the mode, eg. "lha lf".
|
||||
|
||||
q[level] - Quiet mode. Normal running is quiet level 0.
|
||||
|
||||
in list mode, quiet level 2 strips header/footer from
|
||||
listing.
|
||||
|
||||
in extract mode, overwrite is always performed, and:
|
||||
- at quiet level 1, the 'progress bar' is not shown.
|
||||
- at quiet level 2, no messages are printed at all.
|
||||
|
||||
in test mode, behavior is similar to extract mode, but
|
||||
level 2 behavior is similar to level 0.
|
||||
|
||||
in print mode, at quiet level 2 the filename is not
|
||||
printed before the file contents.
|
||||
|
||||
all quiet modes imply 'f', disabling overwrite without
|
||||
confirmation.
|
||||
|
||||
f - Force overwrite. When extracting, existing files are
|
||||
overwritten with no confirmation.
|
||||
|
||||
n - Don't execute commands, just do a dry run of what would
|
||||
be done.
|
||||
|
||||
eg. for lha en:
|
||||
|
||||
EXTRACT lhasa/src/ (directory)
|
||||
EXTRACT lhasa/src/extract.c
|
||||
EXTRACT lhasa/src/extract.c but file is exist.
|
||||
|
||||
eg. for lha tn:
|
||||
|
||||
VERIFY lhasa/src/main.c
|
||||
|
||||
i - Ignore directory path. When extracting, the directory
|
||||
of each file is ignored - they are all extracted into
|
||||
the same directory.
|
||||
|
||||
Also applies to test mode - the output filename of the
|
||||
tested file does not include the directory.
|
||||
|
||||
In print mode, the path is not printed in the header
|
||||
before each file.
|
||||
|
||||
v - Verbose mode, prints extra information.
|
||||
|
||||
in list mode, verbose mode splits the filename onto a
|
||||
separate preceding line and the header level is shown
|
||||
in its normal place.
|
||||
|
||||
in extract mode, verbose mode prints a message when
|
||||
creating a directory. If creating missing parent directories,
|
||||
they are printed in reverse order, eg.
|
||||
|
||||
Making directory "lhasa/src".
|
||||
Making directory "lhasa".
|
||||
lhasa/src/main.c - Melted : o
|
||||
|
||||
w=dir - Specify destination directory to extract files. Must be
|
||||
the last option specified. '=' can be omitted. If combined
|
||||
with 'i', all files get placed in that one directory.
|
||||
|
676
Src/external_dependencies/openmpt-trunk/include/lhasa/src/extract.c
vendored
Normal file
676
Src/external_dependencies/openmpt-trunk/include/lhasa/src/extract.c
vendored
Normal file
@ -0,0 +1,676 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "lib/lha_arch.h"
|
||||
|
||||
#include "extract.h"
|
||||
#include "safe.h"
|
||||
|
||||
// Maximum number of dots in progress output:
|
||||
|
||||
#define MAX_PROGRESS_LEN 58
|
||||
|
||||
typedef struct {
|
||||
int invoked;
|
||||
LHAFileHeader *header;
|
||||
LHAOptions *options;
|
||||
char *filename;
|
||||
char *operation;
|
||||
} ProgressCallbackData;
|
||||
|
||||
// Given a file header structure, get the path to extract to.
|
||||
// Returns a newly allocated string that must be free()d.
|
||||
|
||||
static char *file_full_path(LHAFileHeader *header, LHAOptions *options)
|
||||
{
|
||||
size_t len;
|
||||
char *result;
|
||||
char *p;
|
||||
|
||||
// Full path, or filename only?
|
||||
|
||||
len = 0;
|
||||
|
||||
if (options->extract_path != NULL) {
|
||||
len += strlen(options->extract_path) + 1;
|
||||
}
|
||||
|
||||
if (options->use_path && header->path != NULL) {
|
||||
len += strlen(header->path);
|
||||
}
|
||||
|
||||
if (header->filename != NULL) {
|
||||
len += strlen(header->filename);
|
||||
}
|
||||
|
||||
result = malloc(len + 1);
|
||||
|
||||
if (result == NULL) {
|
||||
// TODO?
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result[0] = '\0';
|
||||
|
||||
if (options->extract_path != NULL) {
|
||||
strcat(result, options->extract_path);
|
||||
strcat(result, "/");
|
||||
}
|
||||
|
||||
// Add path. If it is an absolute path (contains a leading '/')
|
||||
// then skip over the leading '/' to make it a relative path.
|
||||
// This prevents the possibility of a security threat with a
|
||||
// malicious archive that might try to write to arbitrary
|
||||
// filesystem locations.
|
||||
// It also removes the double '/' when using the -w option.
|
||||
|
||||
if (options->use_path && header->path != NULL) {
|
||||
p = header->path;
|
||||
while (*p == '/') {
|
||||
++p;
|
||||
}
|
||||
strcat(result, p);
|
||||
}
|
||||
|
||||
// The filename header field might conceivably try to include
|
||||
// a path separator as well, so skip over any leading '/'
|
||||
// here too.
|
||||
|
||||
if (header->filename != NULL) {
|
||||
p = header->filename;
|
||||
while (*p == '/') {
|
||||
++p;
|
||||
}
|
||||
strcat(result, p);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void print_filename(char *filename, char *status)
|
||||
{
|
||||
printf("\r");
|
||||
safe_printf("%s", filename);
|
||||
printf("\t- %s ", status);
|
||||
}
|
||||
|
||||
static void print_filename_brief(char *filename)
|
||||
{
|
||||
printf("\r");
|
||||
safe_printf("%s :", filename);
|
||||
}
|
||||
|
||||
// Callback function invoked during decompression progress.
|
||||
|
||||
static void progress_callback(unsigned int block,
|
||||
unsigned int num_blocks,
|
||||
void *data)
|
||||
{
|
||||
ProgressCallbackData *progress = data;
|
||||
unsigned int factor;
|
||||
unsigned int i;
|
||||
|
||||
progress->invoked = 1;
|
||||
|
||||
// If the quiet mode options are specified, print a limited amount
|
||||
// of information without a progress bar (level 1) or no message
|
||||
// at all (level 2).
|
||||
|
||||
if (progress->options->quiet >= 2) {
|
||||
return;
|
||||
} else if (progress->options->quiet == 1) {
|
||||
if (block == 0) {
|
||||
print_filename_brief(progress->filename);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Scale factor for blocks, so that the line is never too long. When
|
||||
// MAX_PROGRESS_LEN is exceeded, the length is halved (factor=2), then
|
||||
// progressively larger scale factors are applied.
|
||||
|
||||
factor = 1 + (num_blocks / MAX_PROGRESS_LEN);
|
||||
num_blocks = (num_blocks + factor - 1) / factor;
|
||||
|
||||
// First call to specify number of blocks?
|
||||
|
||||
if (block == 0) {
|
||||
print_filename(progress->filename, progress->operation);
|
||||
|
||||
for (i = 0; i < num_blocks; ++i) {
|
||||
printf(".");
|
||||
}
|
||||
|
||||
print_filename(progress->filename, progress->operation);
|
||||
} else if (((block + factor - 1) % factor) == 0) {
|
||||
// Otherwise, signal progress:
|
||||
|
||||
printf("o");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// Print a line to stdout describing a symlink.
|
||||
|
||||
static void print_symlink_line(char *src, char *dest)
|
||||
{
|
||||
safe_printf("Symbolic Link %s -> %s", src, dest);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Perform CRC check of an archived file.
|
||||
|
||||
static int test_archived_file_crc(LHAReader *reader,
|
||||
LHAFileHeader *header,
|
||||
LHAOptions *options)
|
||||
{
|
||||
ProgressCallbackData progress;
|
||||
char *filename;
|
||||
int success;
|
||||
|
||||
filename = file_full_path(header, options);
|
||||
|
||||
if (options->dry_run) {
|
||||
if (strcmp(header->compress_method,
|
||||
LHA_COMPRESS_TYPE_DIR) != 0) {
|
||||
safe_printf("VERIFY %s", filename);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
free(filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
progress.invoked = 0;
|
||||
progress.operation = "Testing :";
|
||||
progress.options = options;
|
||||
progress.filename = filename;
|
||||
progress.header = header;
|
||||
|
||||
success = lha_reader_check(reader, progress_callback, &progress);
|
||||
|
||||
if (progress.invoked && options->quiet < 2) {
|
||||
if (success) {
|
||||
print_filename(filename, "Tested");
|
||||
printf("\n");
|
||||
} else {
|
||||
print_filename(filename, "CRC error");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// TODO: Exit with error
|
||||
}
|
||||
|
||||
free(filename);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Check that the specified directory exists, and create it if it
|
||||
// does not.
|
||||
|
||||
static int check_parent_directory(char *path)
|
||||
{
|
||||
LHAFileType file_type;
|
||||
|
||||
file_type = lha_arch_exists(path);
|
||||
|
||||
switch (file_type) {
|
||||
|
||||
case LHA_FILE_DIRECTORY:
|
||||
// Already exists.
|
||||
break;
|
||||
|
||||
case LHA_FILE_NONE:
|
||||
// Create the missing directory:
|
||||
|
||||
if (!lha_arch_mkdir(path, 0755)) {
|
||||
fprintf(stderr,
|
||||
"Failed to create parent directory %s\n",
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case LHA_FILE_FILE:
|
||||
fprintf(stderr, "Parent path %s is not a directory!\n",
|
||||
path);
|
||||
return 0;
|
||||
|
||||
case LHA_FILE_ERROR:
|
||||
fprintf(stderr, "Failed to stat %s\n", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Given a filename, create its parent directories as necessary.
|
||||
|
||||
static int make_parent_directories(char *orig_path)
|
||||
{
|
||||
int result;
|
||||
char *p;
|
||||
char *path;
|
||||
|
||||
result = 1;
|
||||
|
||||
// Duplicate the path and strip off any trailing '/'s:
|
||||
|
||||
path = strdup(orig_path);
|
||||
|
||||
if (path == NULL) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
p = path + strlen(path) - 1;
|
||||
|
||||
while (p >= path && *p == '/') {
|
||||
*p = '\0';
|
||||
--p;
|
||||
}
|
||||
|
||||
// Iterate through the string, finding each path separator. At
|
||||
// each place, temporarily chop off the end of the path to get
|
||||
// each parent directory in turn.
|
||||
|
||||
for (p = path; *p == '/'; ++p);
|
||||
|
||||
for (;;) {
|
||||
p = strchr(p, '/');
|
||||
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
// Check if this parent directory exists and create it:
|
||||
|
||||
if (!check_parent_directory(path)) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Restore path separator and advance to the next path.
|
||||
|
||||
*p = '/';
|
||||
++p;
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Prompt the user with a message, and return the first character of
|
||||
// the typed response.
|
||||
|
||||
static char prompt_user(char *message)
|
||||
{
|
||||
char result;
|
||||
int c;
|
||||
|
||||
fprintf(stderr, "%s", message);
|
||||
fflush(stderr);
|
||||
|
||||
// Read characters until a newline is found, saving the first
|
||||
// character entered.
|
||||
|
||||
result = 0;
|
||||
|
||||
do {
|
||||
c = getchar();
|
||||
|
||||
if (c < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
result = c;
|
||||
}
|
||||
} while (c != '\n');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// A file to be extracted already exists. Apply the overwrite policy
|
||||
// to decide whether to overwrite the existing file, prompting the
|
||||
// user if necessary.
|
||||
|
||||
static int confirm_file_overwrite(char *filename, LHAOptions *options)
|
||||
{
|
||||
char response;
|
||||
|
||||
switch (options->overwrite_policy) {
|
||||
case LHA_OVERWRITE_PROMPT:
|
||||
break;
|
||||
case LHA_OVERWRITE_SKIP:
|
||||
return 0;
|
||||
case LHA_OVERWRITE_ALL:
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
safe_fprintf(stderr, "%s ", filename);
|
||||
|
||||
response = prompt_user("OverWrite ?(Yes/[No]/All/Skip) ");
|
||||
|
||||
switch (tolower((unsigned int) response)) {
|
||||
case 'y':
|
||||
return 1;
|
||||
case 'n':
|
||||
case '\n':
|
||||
return 0;
|
||||
case 'a':
|
||||
options->overwrite_policy = LHA_OVERWRITE_ALL;
|
||||
return 1;
|
||||
case 's':
|
||||
options->overwrite_policy = LHA_OVERWRITE_SKIP;
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if the file pointed to by the specified header exists.
|
||||
|
||||
static int file_exists(char *filename)
|
||||
{
|
||||
LHAFileType file_type;
|
||||
|
||||
file_type = lha_arch_exists(filename);
|
||||
|
||||
if (file_type == LHA_FILE_ERROR) {
|
||||
fprintf(stderr, "Failed to read file type of '%s'\n", filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return file_type != LHA_FILE_NONE;
|
||||
}
|
||||
|
||||
// Extract an archived file.
|
||||
|
||||
static int extract_archived_file(LHAReader *reader,
|
||||
LHAFileHeader *header,
|
||||
LHAOptions *options)
|
||||
{
|
||||
ProgressCallbackData progress;
|
||||
char *filename;
|
||||
int success;
|
||||
int is_dir, is_symlink;
|
||||
|
||||
filename = file_full_path(header, options);
|
||||
is_symlink = header->symlink_target != NULL;
|
||||
is_dir = !strcmp(header->compress_method, LHA_COMPRESS_TYPE_DIR)
|
||||
&& !is_symlink;
|
||||
|
||||
// If a file already exists with this name, confirm overwrite.
|
||||
|
||||
if (!is_dir && !is_symlink && file_exists(filename)
|
||||
&& !confirm_file_overwrite(filename, options)) {
|
||||
if (options->overwrite_policy == LHA_OVERWRITE_SKIP) {
|
||||
safe_printf("%s : Skipped...", filename);
|
||||
printf("\n");
|
||||
}
|
||||
free(filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// No need to extract directories if use_path is disabled.
|
||||
|
||||
if (!options->use_path && is_dir) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create parent directories for file:
|
||||
|
||||
if (!make_parent_directories(filename)) {
|
||||
free(filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
progress.invoked = 0;
|
||||
progress.operation = "Melting :";
|
||||
progress.options = options;
|
||||
progress.header = header;
|
||||
progress.filename = filename;
|
||||
|
||||
success = lha_reader_extract(reader, filename,
|
||||
progress_callback, &progress);
|
||||
|
||||
if (!lha_reader_current_is_fake(reader) && options->quiet < 2) {
|
||||
if (progress.invoked) {
|
||||
if (success) {
|
||||
print_filename(filename, "Melted");
|
||||
printf("\n");
|
||||
} else {
|
||||
print_filename(filename, "Failure");
|
||||
printf("\n");
|
||||
}
|
||||
} else if (is_symlink) {
|
||||
print_symlink_line(filename, header->symlink_target);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// TODO: Exit with error
|
||||
}
|
||||
|
||||
free(filename);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// lha -t command.
|
||||
|
||||
int test_file_crc(LHAFilter *filter, LHAOptions *options)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = 1;
|
||||
|
||||
for (;;) {
|
||||
LHAFileHeader *header;
|
||||
|
||||
header = lha_filter_next_file(filter);
|
||||
|
||||
if (header == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_archived_file_crc(filter->reader, header, options)) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// lha -en / -xn / -pn:
|
||||
// Simulate extracting an archive file, but just print the operations
|
||||
// that would have been performed to stdout.
|
||||
|
||||
static int extract_archive_dry_run(LHAFilter *filter, LHAOptions *options)
|
||||
{
|
||||
char *filename;
|
||||
int result;
|
||||
|
||||
result = 1;
|
||||
|
||||
for (;;) {
|
||||
LHAFileHeader *header;
|
||||
|
||||
header = lha_filter_next_file(filter);
|
||||
|
||||
if (header == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
filename = file_full_path(header, options);
|
||||
|
||||
// Every line begins the same - "EXTRACT filename..."
|
||||
|
||||
safe_printf("EXTRACT %s", filename);
|
||||
|
||||
// After the filename we might print something extra.
|
||||
// The message if we have an existing file is weird, but this
|
||||
// is just accurately duplicating what the Unix LHA tool says.
|
||||
// The symlink handling is particularly odd - they are treated
|
||||
// as directories (a bleed-through of the way in which
|
||||
// symlinks are stored).
|
||||
|
||||
if (header->symlink_target != NULL) {
|
||||
safe_printf("|%s (directory)", header->symlink_target);
|
||||
} else if (!strcmp(header->compress_method,
|
||||
LHA_COMPRESS_TYPE_DIR)) {
|
||||
safe_printf(" (directory)");
|
||||
} else if (file_exists(filename)) {
|
||||
safe_printf(" but file is exist.");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free(filename);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// lha -e / -x
|
||||
|
||||
int extract_archive(LHAFilter *filter, LHAOptions *options)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (options->dry_run) {
|
||||
return extract_archive_dry_run(filter, options);
|
||||
}
|
||||
|
||||
result = 1;
|
||||
|
||||
for (;;) {
|
||||
LHAFileHeader *header;
|
||||
|
||||
header = lha_filter_next_file(filter);
|
||||
|
||||
if (header == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!extract_archived_file(filter->reader, header, options)) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Dump contents of the current file from the specified reader to stdout.
|
||||
|
||||
static int print_archived_file(LHAReader *reader)
|
||||
{
|
||||
char buf[512];
|
||||
size_t bytes;
|
||||
|
||||
for (;;) {
|
||||
bytes = lha_reader_read(reader, buf, sizeof(buf));
|
||||
if (bytes <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (fwrite(buf, 1, bytes, stdout) < bytes) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// lha -p
|
||||
|
||||
int print_archive(LHAFilter *filter, LHAOptions *options)
|
||||
{
|
||||
LHAFileHeader *header;
|
||||
int is_normal_file;
|
||||
char *full_path;
|
||||
|
||||
// As a weird quirk of Unix LHA, lha -pn is equivalent to lha -en:
|
||||
|
||||
if (options->dry_run) {
|
||||
return extract_archive_dry_run(filter, options);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
header = lha_filter_next_file(filter);
|
||||
|
||||
if (header == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
is_normal_file = strcmp(header->compress_method,
|
||||
LHA_COMPRESS_TYPE_DIR) != 0;
|
||||
|
||||
// Print "header" before the file containing the filename.
|
||||
// For normal files this is a three line separator.
|
||||
// Symlinks get shown in the same way as during extract.
|
||||
// Directories are ignored.
|
||||
|
||||
if (options->quiet < 2) {
|
||||
full_path = file_full_path(header, options);
|
||||
|
||||
if (header->symlink_target != NULL) {
|
||||
print_symlink_line(full_path,
|
||||
header->symlink_target);
|
||||
} else if (is_normal_file) {
|
||||
printf("::::::::\n");
|
||||
safe_printf("%s", full_path);
|
||||
printf("\n::::::::\n");
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
}
|
||||
|
||||
// If this is a normal file, dump the contents to stdout.
|
||||
|
||||
if (is_normal_file && !print_archived_file(filter->reader)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
32
Src/external_dependencies/openmpt-trunk/include/lhasa/src/extract.h
vendored
Normal file
32
Src/external_dependencies/openmpt-trunk/include/lhasa/src/extract.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LHASA_EXTRACT_H
|
||||
#define LHASA_EXTRACT_H
|
||||
|
||||
#include "filter.h"
|
||||
#include "options.h"
|
||||
|
||||
int test_file_crc(LHAFilter *filter, LHAOptions *options);
|
||||
int extract_archive(LHAFilter *filter, LHAOptions *options);
|
||||
int print_archive(LHAFilter *filter, LHAOptions *options);
|
||||
|
||||
#endif /* #ifndef LHASA_EXTRACT_H */
|
||||
|
137
Src/external_dependencies/openmpt-trunk/include/lhasa/src/filter.c
vendored
Normal file
137
Src/external_dependencies/openmpt-trunk/include/lhasa/src/filter.c
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
void lha_filter_init(LHAFilter *filter, LHAReader *reader,
|
||||
char **filters, unsigned int num_filters)
|
||||
{
|
||||
filter->reader = reader;
|
||||
filter->filters = filters;
|
||||
filter->num_filters = num_filters;
|
||||
}
|
||||
|
||||
static int match_glob(char *glob, char *str)
|
||||
{
|
||||
// Iterate through the string, matching each character against the
|
||||
// equivalent character from the glob.
|
||||
|
||||
while (*str != '\0') {
|
||||
|
||||
// When we reach a '*', cut off the remainder of the glob
|
||||
// and shift forward through the string trying to find
|
||||
// a point that matches it.
|
||||
|
||||
if (*glob == '*') {
|
||||
if (match_glob(glob + 1, str)) {
|
||||
return 1;
|
||||
}
|
||||
} else if (*glob == '?' || *glob == *str) {
|
||||
++glob;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
++str;
|
||||
}
|
||||
|
||||
// We have reached the end of the string to match against.
|
||||
// Any '*'s left at the end of the string are superfluous and
|
||||
// can be ignored.
|
||||
|
||||
while (*glob == '*') {
|
||||
++glob;
|
||||
}
|
||||
|
||||
// We now have a successful match only if we have simultaneously
|
||||
// matched the end of the glob.
|
||||
|
||||
return *glob == '\0';
|
||||
}
|
||||
|
||||
static int matches_filter(LHAFilter *filter, LHAFileHeader *header)
|
||||
{
|
||||
size_t path_len;
|
||||
char *path;
|
||||
unsigned int i;
|
||||
|
||||
// Special case: no filters means match all.
|
||||
|
||||
if (filter->num_filters == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
path_len = 0;
|
||||
|
||||
if (header->path != NULL) {
|
||||
path_len += strlen(header->path);
|
||||
}
|
||||
|
||||
if (header->filename != NULL) {
|
||||
path_len += strlen(header->filename);
|
||||
}
|
||||
|
||||
path = malloc(path_len + 1);
|
||||
|
||||
if (path == NULL) {
|
||||
// TODO?
|
||||
return 0;
|
||||
}
|
||||
|
||||
path[0] = '\0';
|
||||
|
||||
if (header->path != NULL) {
|
||||
strcat(path, header->path);
|
||||
}
|
||||
|
||||
if (header->filename != NULL) {
|
||||
strcat(path, header->filename);
|
||||
}
|
||||
|
||||
// Check this path with the list of filters. If one matches,
|
||||
// we must return true.
|
||||
|
||||
for (i = 0; i < filter->num_filters; ++i) {
|
||||
if (match_glob(filter->filters[i], path)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
return i < filter->num_filters;
|
||||
}
|
||||
|
||||
LHAFileHeader *lha_filter_next_file(LHAFilter *filter)
|
||||
{
|
||||
LHAFileHeader *header;
|
||||
|
||||
// Read through headers until we find one that matches.
|
||||
|
||||
do {
|
||||
header = lha_reader_next_file(filter->reader);
|
||||
} while (header != NULL && !matches_filter(filter, header));
|
||||
|
||||
return header;
|
||||
}
|
||||
|
61
Src/external_dependencies/openmpt-trunk/include/lhasa/src/filter.h
vendored
Normal file
61
Src/external_dependencies/openmpt-trunk/include/lhasa/src/filter.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LHASA_FILTER_H
|
||||
#define LHASA_FILTER_H
|
||||
|
||||
#include "lha_reader.h"
|
||||
|
||||
typedef struct _LHAFilter LHAFilter;
|
||||
|
||||
struct _LHAFilter {
|
||||
LHAReader *reader;
|
||||
char **filters;
|
||||
unsigned int num_filters;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a @ref LHAFilter structure to read files from
|
||||
* the specified @ref LHAReader, applying the specified list of
|
||||
* filters.
|
||||
*
|
||||
* @param filter The filter structure to initialize.
|
||||
* @param reader The reader object to read files from.
|
||||
* @param filters List of strings containing glob-style filters
|
||||
* to apply to the filenames to read.
|
||||
* @param num_filters Number of filters in the 'filters' array.
|
||||
*/
|
||||
|
||||
void lha_filter_init(LHAFilter *filter, LHAReader *reader,
|
||||
char **filters, unsigned int num_filters);
|
||||
|
||||
/**
|
||||
* Read the next file from the input stream.
|
||||
*
|
||||
* @param filter The filter structure.
|
||||
* @return File header structure for the next file that
|
||||
* matches the filters, or NULL for end of file
|
||||
* or error.
|
||||
*/
|
||||
|
||||
LHAFileHeader *lha_filter_next_file(LHAFilter *filter);
|
||||
|
||||
#endif /* #ifndef LHASA_FILTER_H */
|
||||
|
682
Src/external_dependencies/openmpt-trunk/include/lhasa/src/list.c
vendored
Normal file
682
Src/external_dependencies/openmpt-trunk/include/lhasa/src/list.c
vendored
Normal file
@ -0,0 +1,682 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "lha_reader.h"
|
||||
#include "list.h"
|
||||
#include "safe.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned int num_files;
|
||||
unsigned int compressed_length;
|
||||
unsigned int length;
|
||||
unsigned int timestamp;
|
||||
} FileStatistics;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned int width;
|
||||
void (*handler)(LHAFileHeader *header);
|
||||
void (*footer)(FileStatistics *stats);
|
||||
} ListColumn;
|
||||
|
||||
// Display OS type:
|
||||
|
||||
static char *os_type_to_string(uint8_t os_type)
|
||||
{
|
||||
switch (os_type) {
|
||||
case LHA_OS_TYPE_MSDOS:
|
||||
return "[MS-DOS]";
|
||||
case LHA_OS_TYPE_WIN95:
|
||||
return "[Win9x]";
|
||||
case LHA_OS_TYPE_WINNT:
|
||||
return "[WinNT]";
|
||||
case LHA_OS_TYPE_UNIX:
|
||||
return "[Unix]";
|
||||
case LHA_OS_TYPE_OS2:
|
||||
return "[OS/2]";
|
||||
case LHA_OS_TYPE_CPM:
|
||||
return "[CP/M]";
|
||||
case LHA_OS_TYPE_MACOS:
|
||||
return "[Mac OS]";
|
||||
case LHA_OS_TYPE_JAVA:
|
||||
return "[Java]";
|
||||
case LHA_OS_TYPE_FLEX:
|
||||
return "[FLEX]";
|
||||
case LHA_OS_TYPE_RUNSER:
|
||||
return "[Runser]";
|
||||
case LHA_OS_TYPE_TOWNSOS:
|
||||
return "[TownsOS]";
|
||||
case LHA_OS_TYPE_OS9:
|
||||
return "[OS-9]";
|
||||
case LHA_OS_TYPE_OS9_68K:
|
||||
return "[OS-9/68K]";
|
||||
case LHA_OS_TYPE_OS386:
|
||||
return "[OS-386]";
|
||||
case LHA_OS_TYPE_HUMAN68K:
|
||||
return "[Human68K]";
|
||||
case LHA_OS_TYPE_ATARI:
|
||||
return "[Atari]";
|
||||
case LHA_OS_TYPE_AMIGA:
|
||||
return "[Amiga]";
|
||||
case LHA_OS_TYPE_UNKNOWN:
|
||||
return "[generic]";
|
||||
default:
|
||||
return "[unknown]";
|
||||
}
|
||||
}
|
||||
|
||||
// Print Unix file permissions.
|
||||
|
||||
static void unix_permissions_print(LHAFileHeader *header)
|
||||
{
|
||||
const char *perms = "rwxrwxrwx";
|
||||
unsigned int i;
|
||||
|
||||
if (strcmp(header->compress_method, LHA_COMPRESS_TYPE_DIR) != 0) {
|
||||
printf("-");
|
||||
} else if (header->symlink_target != NULL) {
|
||||
printf("l");
|
||||
} else {
|
||||
printf("d");
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (header->unix_perms & (1U << (8 - i))) {
|
||||
printf("%c", perms[i]);
|
||||
} else {
|
||||
printf("-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print OS-9 file permissions.
|
||||
|
||||
static void os9_permissions_print(LHAFileHeader *header)
|
||||
{
|
||||
const char *perms = "sewrewr";
|
||||
unsigned int i;
|
||||
|
||||
if (strcmp(header->compress_method, LHA_COMPRESS_TYPE_DIR) != 0) {
|
||||
printf("-");
|
||||
} else {
|
||||
printf("d");
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; ++i) {
|
||||
if (header->os9_perms & (1U << (6 - i))) {
|
||||
printf("%c", perms[i]);
|
||||
} else {
|
||||
printf("-");
|
||||
}
|
||||
}
|
||||
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
// File permissions
|
||||
|
||||
static void permission_column_print(LHAFileHeader *header)
|
||||
{
|
||||
// Print permissions. If we do not have any permissions to
|
||||
// print, fall back to printing the OS type.
|
||||
|
||||
if (LHA_FILE_HAVE_EXTRA(header, LHA_FILE_OS9_PERMS)) {
|
||||
os9_permissions_print(header);
|
||||
} else if (LHA_FILE_HAVE_EXTRA(header, LHA_FILE_UNIX_PERMS)) {
|
||||
unix_permissions_print(header);
|
||||
} else {
|
||||
printf("%-10s", os_type_to_string(header->os_type));
|
||||
}
|
||||
}
|
||||
|
||||
static void permission_column_footer(FileStatistics *stats)
|
||||
{
|
||||
printf(" Total ");
|
||||
}
|
||||
|
||||
static ListColumn permission_column = {
|
||||
" PERMSSN", 10,
|
||||
permission_column_print,
|
||||
permission_column_footer
|
||||
};
|
||||
|
||||
// Unix UID/GID
|
||||
|
||||
static void unix_uid_gid_column_print(LHAFileHeader *header)
|
||||
{
|
||||
if (LHA_FILE_HAVE_EXTRA(header, LHA_FILE_UNIX_UID_GID)) {
|
||||
printf("%5i/%-5i", header->unix_uid, header->unix_gid);
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
static void unix_uid_gid_column_footer(FileStatistics *stats)
|
||||
{
|
||||
// The UID/GID column has the total number of files
|
||||
// listed below it.
|
||||
|
||||
if (stats->num_files == 1) {
|
||||
printf("%5i file ", stats->num_files);
|
||||
} else {
|
||||
printf("%5i files", stats->num_files);
|
||||
}
|
||||
}
|
||||
|
||||
static ListColumn unix_uid_gid_column = {
|
||||
" UID GID", 11,
|
||||
unix_uid_gid_column_print,
|
||||
unix_uid_gid_column_footer
|
||||
};
|
||||
|
||||
// Compressed file size
|
||||
|
||||
static void packed_column_print(LHAFileHeader *header)
|
||||
{
|
||||
printf("%7lu", (unsigned long) header->compressed_length);
|
||||
}
|
||||
|
||||
static void packed_column_footer(FileStatistics *stats)
|
||||
{
|
||||
printf("%7lu", (unsigned long) stats->compressed_length);
|
||||
}
|
||||
|
||||
static ListColumn packed_column = {
|
||||
" PACKED", 7,
|
||||
packed_column_print,
|
||||
packed_column_footer
|
||||
};
|
||||
|
||||
// Uncompressed file size
|
||||
|
||||
static void size_column_print(LHAFileHeader *header)
|
||||
{
|
||||
printf("%7lu", (unsigned long) header->length);
|
||||
}
|
||||
|
||||
static void size_column_footer(FileStatistics *stats)
|
||||
{
|
||||
printf("%7lu", (unsigned long) stats->length);
|
||||
}
|
||||
|
||||
static ListColumn size_column = {
|
||||
" SIZE", 7,
|
||||
size_column_print,
|
||||
size_column_footer
|
||||
};
|
||||
|
||||
// Compression ratio
|
||||
|
||||
static float compression_percent(size_t compressed, size_t uncompressed)
|
||||
{
|
||||
if (uncompressed > 0) {
|
||||
return ((float) compressed * 100.0f) / (float) uncompressed;
|
||||
} else {
|
||||
return 100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void ratio_column_print(LHAFileHeader *header)
|
||||
{
|
||||
if (!strcmp(header->compress_method, "-lhd-")) {
|
||||
printf("******");
|
||||
} else {
|
||||
printf("%5.1f%%", compression_percent(header->compressed_length,
|
||||
header->length));
|
||||
}
|
||||
}
|
||||
|
||||
static void ratio_column_footer(FileStatistics *stats)
|
||||
{
|
||||
if (stats->length == 0) {
|
||||
printf("******");
|
||||
} else {
|
||||
printf("%5.1f%%", compression_percent(stats->compressed_length,
|
||||
stats->length));
|
||||
}
|
||||
}
|
||||
|
||||
static ListColumn ratio_column = {
|
||||
" RATIO", 6,
|
||||
ratio_column_print,
|
||||
ratio_column_footer
|
||||
};
|
||||
|
||||
// Compression method and CRC checksum
|
||||
|
||||
static void method_crc_column_print(LHAFileHeader *header)
|
||||
{
|
||||
printf("%-5s %04x", header->compress_method, header->crc);
|
||||
}
|
||||
|
||||
static ListColumn method_crc_column = {
|
||||
"METHOD CRC", 10,
|
||||
method_crc_column_print
|
||||
};
|
||||
|
||||
// Get the current time.
|
||||
|
||||
static time_t get_now_time(void)
|
||||
{
|
||||
// For test builds, allow the current time to be overridden using
|
||||
// an environment variable. This is because the list output can
|
||||
// change depending on the current date.
|
||||
|
||||
#ifdef TEST_BUILD
|
||||
char *env_val;
|
||||
unsigned int result;
|
||||
|
||||
env_val = getenv("TEST_NOW_TIME");
|
||||
|
||||
if (env_val != NULL
|
||||
&& sscanf(env_val, "%u", &result) == 1) {
|
||||
return (time_t) result;
|
||||
}
|
||||
#endif
|
||||
|
||||
return time(NULL);
|
||||
}
|
||||
|
||||
// File timestamp
|
||||
|
||||
static void output_timestamp(unsigned int timestamp)
|
||||
{
|
||||
const char *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
struct tm *ts;
|
||||
time_t tmp;
|
||||
|
||||
if (timestamp == 0) {
|
||||
printf(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = (time_t) timestamp;
|
||||
ts = localtime(&tmp);
|
||||
|
||||
// Print date:
|
||||
|
||||
printf("%s %2d ", months[ts->tm_mon], ts->tm_mday);
|
||||
|
||||
// If this is an old time (more than 6 months), print the year.
|
||||
// For recent timestamps, print the time.
|
||||
|
||||
tmp = get_now_time();
|
||||
|
||||
if ((time_t) timestamp > tmp - 6 * 30 * 24 * 60 * 60) {
|
||||
printf("%02i:%02i", ts->tm_hour, ts->tm_min);
|
||||
} else {
|
||||
printf(" %04i", ts->tm_year + 1900);
|
||||
}
|
||||
}
|
||||
|
||||
static void timestamp_column_print(LHAFileHeader *header)
|
||||
{
|
||||
output_timestamp(header->timestamp);
|
||||
};
|
||||
|
||||
static void timestamp_column_footer(FileStatistics *stats)
|
||||
{
|
||||
output_timestamp(stats->timestamp);
|
||||
};
|
||||
|
||||
static ListColumn timestamp_column = {
|
||||
" STAMP", 12,
|
||||
timestamp_column_print,
|
||||
timestamp_column_footer
|
||||
};
|
||||
|
||||
// Filename
|
||||
|
||||
static void name_column_print(LHAFileHeader *header)
|
||||
{
|
||||
if (header->path != NULL) {
|
||||
safe_printf("%s", header->path);
|
||||
}
|
||||
if (header->filename != NULL) {
|
||||
safe_printf("%s", header->filename);
|
||||
}
|
||||
if (header->symlink_target != NULL) {
|
||||
safe_printf(" -> %s", header->symlink_target);
|
||||
}
|
||||
}
|
||||
|
||||
static ListColumn name_column = {
|
||||
" NAME", 20,
|
||||
name_column_print
|
||||
};
|
||||
|
||||
static ListColumn short_name_column = {
|
||||
" NAME", 13,
|
||||
name_column_print
|
||||
};
|
||||
|
||||
// "Separate line" filename display. Used when the 'v' option
|
||||
// is added.
|
||||
|
||||
static void whole_line_name_column_print(LHAFileHeader *header)
|
||||
{
|
||||
if (header->path != NULL) {
|
||||
safe_printf("%s", header->path);
|
||||
}
|
||||
if (header->filename != NULL) {
|
||||
safe_printf("%s", header->filename);
|
||||
}
|
||||
|
||||
// For wide filename mode (-v), | is used as the symlink separator,
|
||||
// instead of ->. The reason is that this is how symlinks are
|
||||
// represented within the file headers - the Unix LHA tool only
|
||||
// does the parsing in normal list mode.
|
||||
|
||||
if (header->symlink_target != NULL) {
|
||||
safe_printf("|%s", header->symlink_target);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static ListColumn whole_line_name_column = {
|
||||
"", 0,
|
||||
whole_line_name_column_print
|
||||
};
|
||||
|
||||
// Header level column. Used when the 'v' option is added.
|
||||
|
||||
static void header_level_column_print(LHAFileHeader *header)
|
||||
{
|
||||
printf(" [%i]", header->header_level);
|
||||
}
|
||||
|
||||
static ListColumn header_level_column = {
|
||||
"", 0,
|
||||
header_level_column_print
|
||||
};
|
||||
|
||||
// Get the last "real" column in a list of columns. This is the last
|
||||
// column with a width > 0. Beyond this last column it isn't necessary
|
||||
// to print any more whitespace.
|
||||
|
||||
static ListColumn *last_column(ListColumn **columns)
|
||||
{
|
||||
ListColumn *last;
|
||||
unsigned int i;
|
||||
|
||||
last = NULL;
|
||||
|
||||
for (i = 0; columns[i] != NULL; ++i) {
|
||||
if (columns[i]->width != 0) {
|
||||
last = columns[i];
|
||||
}
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
// Print the names of the column headings at the top of the file list.
|
||||
|
||||
static void print_list_headings(ListColumn **columns)
|
||||
{
|
||||
ListColumn *last;
|
||||
unsigned int i, j;
|
||||
|
||||
last = last_column(columns);
|
||||
|
||||
for (i = 0; columns[i] != NULL; ++i) {
|
||||
j = (unsigned) printf("%s", columns[i]->name);
|
||||
|
||||
if (columns[i]->width > 0 && columns[i] != last) {
|
||||
for (; j < columns[i]->width + 1; ++j) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Print separator lines shown at top and bottom of file list.
|
||||
|
||||
static void print_list_separators(ListColumn **columns)
|
||||
{
|
||||
ListColumn *last;
|
||||
unsigned int i, j;
|
||||
|
||||
last = last_column(columns);
|
||||
|
||||
for (i = 0; columns[i] != NULL; ++i) {
|
||||
for (j = 0; j < columns[i]->width; ++j) {
|
||||
printf("-");
|
||||
}
|
||||
|
||||
if (columns[i]->width != 0 && columns[i] != last) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Print a row in the list corresponding to a file.
|
||||
|
||||
static void print_columns(ListColumn **columns, LHAFileHeader *header)
|
||||
{
|
||||
ListColumn *last;
|
||||
unsigned int i;
|
||||
|
||||
last = last_column(columns);
|
||||
|
||||
for (i = 0; columns[i] != NULL; ++i) {
|
||||
columns[i]->handler(header);
|
||||
|
||||
if (columns[i]->width != 0 && columns[i] != last) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Print footer information shown at end of list (overall file stats)
|
||||
|
||||
static void print_footers(ListColumn **columns, FileStatistics *stats)
|
||||
{
|
||||
unsigned int i, j, len;
|
||||
unsigned int num_columns;
|
||||
|
||||
// Work out how many columns there are to print, ignoring trailing
|
||||
// columns that have no footer:
|
||||
|
||||
num_columns = 0;
|
||||
|
||||
for (i = 0; columns[i] != NULL; ++i) {
|
||||
++num_columns;
|
||||
}
|
||||
|
||||
while (num_columns > 0 && columns[num_columns-1]->footer == NULL) {
|
||||
--num_columns;
|
||||
}
|
||||
|
||||
// Print footers for each column.
|
||||
// Some columns do not have footers: fill in with spaces instead.
|
||||
|
||||
for (i = 0; i < num_columns; ++i) {
|
||||
if (columns[i]->footer != NULL) {
|
||||
columns[i]->footer(stats);
|
||||
} else if (i + 1 < num_columns) {
|
||||
len = strlen(columns[i]->name);
|
||||
|
||||
for (j = 0; j < len; ++j) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if (columns[i]->width != 0 && i + 1 < num_columns) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static unsigned int read_file_timestamp(FILE *fstream)
|
||||
{
|
||||
struct stat data;
|
||||
|
||||
if (fstat(fileno(fstream), &data) != 0) {
|
||||
return (unsigned int) -1;
|
||||
}
|
||||
|
||||
return (unsigned int) data.st_mtime;
|
||||
}
|
||||
|
||||
// List contents of file, using the specified columns.
|
||||
// Different columns are provided for basic and verbose modes.
|
||||
|
||||
static void list_file_contents(LHAFilter *filter, FILE *fstream,
|
||||
LHAOptions *options, ListColumn **columns)
|
||||
{
|
||||
FileStatistics stats;
|
||||
|
||||
if (options->quiet < 2) {
|
||||
print_list_headings(columns);
|
||||
print_list_separators(columns);
|
||||
}
|
||||
|
||||
stats.num_files = 0;
|
||||
stats.length = 0;
|
||||
stats.compressed_length = 0;
|
||||
stats.timestamp = read_file_timestamp(fstream);
|
||||
|
||||
for (;;) {
|
||||
LHAFileHeader *header;
|
||||
|
||||
header = lha_filter_next_file(filter);
|
||||
|
||||
if (header == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
print_columns(columns, header);
|
||||
|
||||
++stats.num_files;
|
||||
stats.length += header->length;
|
||||
stats.compressed_length += header->compressed_length;
|
||||
}
|
||||
|
||||
if (options->quiet < 2) {
|
||||
print_list_separators(columns);
|
||||
print_footers(columns, &stats);
|
||||
}
|
||||
}
|
||||
|
||||
// Used for lha -l:
|
||||
|
||||
static ListColumn *normal_column_headers[] = {
|
||||
&permission_column,
|
||||
&unix_uid_gid_column,
|
||||
&size_column,
|
||||
&ratio_column,
|
||||
×tamp_column,
|
||||
&name_column,
|
||||
NULL
|
||||
};
|
||||
|
||||
// Used for lha -lv:
|
||||
|
||||
static ListColumn *normal_column_headers_verbose[] = {
|
||||
&whole_line_name_column,
|
||||
&permission_column,
|
||||
&unix_uid_gid_column,
|
||||
&size_column,
|
||||
&ratio_column,
|
||||
×tamp_column,
|
||||
&header_level_column,
|
||||
NULL
|
||||
};
|
||||
|
||||
// lha -l command.
|
||||
|
||||
void list_file_basic(LHAFilter *filter, LHAOptions *options, FILE *fstream)
|
||||
{
|
||||
ListColumn **headers;
|
||||
|
||||
if (options->verbose) {
|
||||
headers = normal_column_headers_verbose;
|
||||
} else {
|
||||
headers = normal_column_headers;
|
||||
}
|
||||
|
||||
list_file_contents(filter, fstream, options, headers);
|
||||
}
|
||||
|
||||
// Used for lha -v:
|
||||
|
||||
static ListColumn *verbose_column_headers[] = {
|
||||
&permission_column,
|
||||
&unix_uid_gid_column,
|
||||
&packed_column,
|
||||
&size_column,
|
||||
&ratio_column,
|
||||
&method_crc_column,
|
||||
×tamp_column,
|
||||
&short_name_column,
|
||||
NULL
|
||||
};
|
||||
|
||||
// Used for lha -vv:
|
||||
|
||||
static ListColumn *verbose_column_headers_verbose[] = {
|
||||
&whole_line_name_column,
|
||||
&permission_column,
|
||||
&unix_uid_gid_column,
|
||||
&packed_column,
|
||||
&size_column,
|
||||
&ratio_column,
|
||||
&method_crc_column,
|
||||
×tamp_column,
|
||||
&header_level_column,
|
||||
NULL
|
||||
};
|
||||
|
||||
// lha -v command.
|
||||
|
||||
void list_file_verbose(LHAFilter *filter, LHAOptions *options, FILE *fstream)
|
||||
{
|
||||
ListColumn **headers;
|
||||
|
||||
if (options->verbose) {
|
||||
headers = verbose_column_headers_verbose;
|
||||
} else {
|
||||
headers = verbose_column_headers;
|
||||
}
|
||||
|
||||
list_file_contents(filter, fstream, options, headers);
|
||||
}
|
||||
|
31
Src/external_dependencies/openmpt-trunk/include/lhasa/src/list.h
vendored
Normal file
31
Src/external_dependencies/openmpt-trunk/include/lhasa/src/list.h
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LHASA_LIST_H
|
||||
#define LHASA_LIST_H
|
||||
|
||||
#include "filter.h"
|
||||
#include "options.h"
|
||||
|
||||
void list_file_basic(LHAFilter *filter, LHAOptions *options, FILE *fstream);
|
||||
void list_file_verbose(LHAFilter *filter, LHAOptions *options, FILE *fstream);
|
||||
|
||||
#endif /* #ifndef LHASA_LIST_H */
|
||||
|
275
Src/external_dependencies/openmpt-trunk/include/lhasa/src/main.c
vendored
Normal file
275
Src/external_dependencies/openmpt-trunk/include/lhasa/src/main.c
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lib/lha_arch.h"
|
||||
#include "lha_reader.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "extract.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef enum {
|
||||
MODE_UNKNOWN,
|
||||
MODE_LIST,
|
||||
MODE_LIST_VERBOSE,
|
||||
MODE_CRC_CHECK,
|
||||
MODE_EXTRACT,
|
||||
MODE_PRINT
|
||||
} ProgramMode;
|
||||
|
||||
static void help_page(char *progname)
|
||||
{
|
||||
printf(
|
||||
PACKAGE_NAME " v" PACKAGE_VERSION " command line LHA tool "
|
||||
"- Copyright (C) 2011,2012 Simon Howard\n"
|
||||
"usage: %s [-]{lvtxe[q{num}][finv]}[w=<dir>] archive_file [file...]\n"
|
||||
"commands: options:\n"
|
||||
" l,v List / Verbose List f Force overwrite (no prompt)\n"
|
||||
" t Test file CRC in archive i Ignore directory path\n"
|
||||
" x,e Extract from archive n Perform dry run\n"
|
||||
" p Print to stdout from archive q{num} Quiet mode\n"
|
||||
" v Verbose\n"
|
||||
" w=<dir> Specify extract directory\n"
|
||||
, progname);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static int do_command(ProgramMode mode, char *filename,
|
||||
LHAOptions *options,
|
||||
char **filters, unsigned int num_filters)
|
||||
{
|
||||
FILE *fstream;
|
||||
LHAInputStream *stream;
|
||||
LHAReader *reader;
|
||||
LHAFilter filter;
|
||||
int result;
|
||||
|
||||
if (!strcmp(filename, "-")) {
|
||||
fstream = stdin;
|
||||
} else {
|
||||
fstream = fopen(filename, "rb");
|
||||
|
||||
if (fstream == NULL) {
|
||||
fprintf(stderr, "LHa: Error: %s %s\n",
|
||||
filename, strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
stream = lha_input_stream_from_FILE(fstream);
|
||||
reader = lha_reader_new(stream);
|
||||
lha_filter_init(&filter, reader, filters, num_filters);
|
||||
|
||||
result = 1;
|
||||
|
||||
switch (mode) {
|
||||
case MODE_LIST:
|
||||
list_file_basic(&filter, options, fstream);
|
||||
break;
|
||||
|
||||
case MODE_LIST_VERBOSE:
|
||||
list_file_verbose(&filter, options, fstream);
|
||||
break;
|
||||
|
||||
case MODE_CRC_CHECK:
|
||||
result = test_file_crc(&filter, options);
|
||||
break;
|
||||
|
||||
case MODE_EXTRACT:
|
||||
result = extract_archive(&filter, options);
|
||||
break;
|
||||
|
||||
case MODE_PRINT:
|
||||
result = print_archive(&filter, options);
|
||||
break;
|
||||
|
||||
case MODE_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
lha_reader_free(reader);
|
||||
lha_input_stream_free(stream);
|
||||
|
||||
fclose(fstream);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void init_options(LHAOptions *options)
|
||||
{
|
||||
options->overwrite_policy = LHA_OVERWRITE_PROMPT;
|
||||
options->quiet = 0;
|
||||
options->verbose = 0;
|
||||
options->dry_run = 0;
|
||||
options->extract_path = NULL;
|
||||
options->use_path = 1;
|
||||
}
|
||||
|
||||
// Determine the program mode from the first character of the command
|
||||
// argument.
|
||||
|
||||
static ProgramMode mode_for_char(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'l':
|
||||
return MODE_LIST;
|
||||
case 'v':
|
||||
return MODE_LIST_VERBOSE;
|
||||
case 't':
|
||||
return MODE_CRC_CHECK;
|
||||
case 'e':
|
||||
case 'x':
|
||||
return MODE_EXTRACT;
|
||||
case 'p':
|
||||
return MODE_PRINT;
|
||||
default:
|
||||
return MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the option flags from the command argument.
|
||||
|
||||
static int parse_options(char *arg, LHAOptions *options)
|
||||
{
|
||||
for (; *arg != '\0'; ++arg) {
|
||||
switch (*arg) {
|
||||
// Force overwrite of existing files.
|
||||
case 'f':
|
||||
options->overwrite_policy = LHA_OVERWRITE_ALL;
|
||||
break;
|
||||
|
||||
// -i option turns off paths for extract.
|
||||
case 'i':
|
||||
options->use_path = 0;
|
||||
break;
|
||||
|
||||
// Dry run?
|
||||
case 'n':
|
||||
options->dry_run = 1;
|
||||
break;
|
||||
|
||||
// Quiet mode parsing. The quiet 'level' can be
|
||||
// specified - if the level is omitted, level 2
|
||||
// is implied. All quiet mode options imply
|
||||
// -f (overwrite without confirmation).
|
||||
case 'q':
|
||||
if (arg[1] >= '0' && arg[1] <= '9') {
|
||||
++arg;
|
||||
options->quiet = *arg - '0';
|
||||
} else {
|
||||
options->quiet = 2;
|
||||
}
|
||||
options->overwrite_policy = LHA_OVERWRITE_ALL;
|
||||
break;
|
||||
|
||||
// Verbose mode.
|
||||
case 'v':
|
||||
options->verbose = 1;
|
||||
break;
|
||||
|
||||
// Specify extract directory: must be last option
|
||||
// specified. Optional '=' separator.
|
||||
case 'w':
|
||||
++arg;
|
||||
if (*arg == '=') {
|
||||
++arg;
|
||||
}
|
||||
options->extract_path = arg;
|
||||
arg += strlen(arg) - 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the command line options, initializing the options structure
|
||||
* used by the main program code.
|
||||
*
|
||||
* @param cmd The 'command' argument (first command line option).
|
||||
* @param mode Pointer to variable to store program mode.
|
||||
* @param options Pointer to options structure to initialize.
|
||||
* @return Non-zero if successful.
|
||||
*/
|
||||
|
||||
static int parse_command_line(char *cmd, ProgramMode *mode,
|
||||
LHAOptions *options)
|
||||
{
|
||||
// Parse program mode argument. Initial '-' is ignored.
|
||||
|
||||
if (*cmd == '-') {
|
||||
++cmd;
|
||||
}
|
||||
|
||||
*mode = mode_for_char(*cmd);
|
||||
|
||||
if (*mode == MODE_UNKNOWN) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse remaining options.
|
||||
|
||||
if (!parse_options(cmd + 1, options)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ProgramMode mode;
|
||||
LHAOptions options;
|
||||
|
||||
#ifdef TEST_BUILD
|
||||
// When running tests, give output to stdout in binary mode;
|
||||
// on Windows, this gives the expected output (which was
|
||||
// constructed for Unix):
|
||||
|
||||
lha_arch_set_binary(stdout);
|
||||
#endif
|
||||
|
||||
// Parse the command line options and run command.
|
||||
// As a shortcut, a single argument can be provided to list the
|
||||
// contents of an archive ("lha foo.lzh" == "lha l foo.lzh").
|
||||
|
||||
init_options(&options);
|
||||
|
||||
if (argc >= 3 && parse_command_line(argv[1], &mode, &options)) {
|
||||
return !do_command(mode, argv[2], &options,
|
||||
argv + 3, argc - 3);
|
||||
} else if (argc == 2) {
|
||||
return !do_command(MODE_LIST, argv[1], &options, NULL, 0);
|
||||
} else {
|
||||
help_page(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
64
Src/external_dependencies/openmpt-trunk/include/lhasa/src/options.h
vendored
Normal file
64
Src/external_dependencies/openmpt-trunk/include/lhasa/src/options.h
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LHASA_OPTIONS_H
|
||||
#define LHASA_OPTIONS_H
|
||||
|
||||
typedef enum {
|
||||
LHA_OVERWRITE_PROMPT,
|
||||
LHA_OVERWRITE_SKIP,
|
||||
LHA_OVERWRITE_ALL
|
||||
} LHAOverwritePolicy;
|
||||
|
||||
// Options structure. Populated from command line arguments.
|
||||
|
||||
typedef struct {
|
||||
|
||||
// Policy to take when extracting files and a file
|
||||
// already exists.
|
||||
|
||||
LHAOverwritePolicy overwrite_policy;
|
||||
|
||||
// "Quiet" level. Normal operation is level 0.
|
||||
|
||||
int quiet;
|
||||
|
||||
// "Verbose" mode.
|
||||
|
||||
int verbose;
|
||||
|
||||
// If true, just perform a dry run of the operations that
|
||||
// would normally be performed, printing messages.
|
||||
|
||||
int dry_run;
|
||||
|
||||
// If not NULL, specifies a path into which to extract files.
|
||||
|
||||
char *extract_path;
|
||||
|
||||
// If true, use the directory path for files - otherwise,
|
||||
// the directory path is ignored.
|
||||
|
||||
int use_path;
|
||||
|
||||
} LHAOptions;
|
||||
|
||||
#endif /* #ifndef LHASA_OPTIONS_H */
|
||||
|
107
Src/external_dependencies/openmpt-trunk/include/lhasa/src/safe.c
vendored
Normal file
107
Src/external_dependencies/openmpt-trunk/include/lhasa/src/safe.c
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/lha_arch.h"
|
||||
|
||||
// Routines for safe terminal output.
|
||||
//
|
||||
// Data in LHA files (eg. filenames) may contain malicious string
|
||||
// data. If printed carelessly, this can include terminal emulator
|
||||
// commands that cause very unpleasant things to occur. For more
|
||||
// information, see:
|
||||
//
|
||||
// http://marc.info/?l=bugtraq&m=104612710031920&w=2
|
||||
//
|
||||
// Quote:
|
||||
// > Many of the features supported by popular terminal emulator
|
||||
// > software can be abused when un-trusted data is displayed on the
|
||||
// > screen. The impact of this abuse can range from annoying screen
|
||||
// > garbage to a complete system compromise.
|
||||
|
||||
// TODO: This may not be ideal behavior for handling files with
|
||||
// names that contain Unicode characters.
|
||||
|
||||
static void safe_output(FILE *stream, unsigned char *str)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
for (p = str; *p != '\0'; ++p) {
|
||||
|
||||
// Accept only plain ASCII characters.
|
||||
// Control characters (0x00-0x1f) are rejected,
|
||||
// as is 0x7f and all characters in the upper range.
|
||||
|
||||
if (*p < 0x20 || *p >= 0x7f) {
|
||||
*p = '?';
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stream, "%s", str);
|
||||
}
|
||||
|
||||
// Version of printf() that strips out any potentially malicious
|
||||
// characters from the outputted string.
|
||||
// Note: all escape characters are considered potentially malicious,
|
||||
// including newline characters.
|
||||
|
||||
int safe_fprintf(FILE *stream, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int result;
|
||||
unsigned char *str;
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
result = lha_arch_vasprintf((char **) &str, format, args);
|
||||
if (str == NULL) {
|
||||
exit(-1);
|
||||
}
|
||||
safe_output(stream, str);
|
||||
free(str);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int safe_printf(char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int result;
|
||||
unsigned char *str;
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
result = lha_arch_vasprintf((char **) &str, format, args);
|
||||
if (str == NULL) {
|
||||
exit(-1);
|
||||
}
|
||||
safe_output(stdout, str);
|
||||
free(str);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
28
Src/external_dependencies/openmpt-trunk/include/lhasa/src/safe.h
vendored
Normal file
28
Src/external_dependencies/openmpt-trunk/include/lhasa/src/safe.h
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2011, 2012, Simon Howard
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LHASA_SAFE_H
|
||||
#define LHASA_SAFE_H
|
||||
|
||||
int safe_fprintf(FILE *stream, char *format, ...);
|
||||
int safe_printf(char *format, ...);
|
||||
|
||||
#endif /* #ifndef LHASA_SAFE_H */
|
||||
|
Reference in New Issue
Block a user