Skip to content

Commit

Permalink
Add option to set the modification date/time
Browse files Browse the repository at this point in the history
This also adds an API function for getting an Unix timestamp
(and updates the man page)
  • Loading branch information
TheComputerGuy96 committed Dec 14, 2024
1 parent a70ab03 commit 90b2a52
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
15 changes: 15 additions & 0 deletions lib/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,21 @@ bool unshield_file_iso_date (Unshield* unshield, int index, char* buf, size_t si
return fd ? true : false;
}/*}}}*/

time_t unshield_file_timestamp (Unshield* unshield, int index)/*{{{*/
{
FileDescriptor* fd = unshield_get_file_descriptor(unshield, index);
struct tm date;

if (fd)
{
unshield_dos_to_tm(fd->dos_date, fd->dos_time, &date);
return mktime(&date);
}

unshield_warning("Failed to get file descriptor %i", index);
return 0;
}/*}}}*/

bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename)
{
/* XXX: Thou Shalt Not Cut & Paste... */
Expand Down
1 change: 1 addition & 0 deletions lib/libunshield.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ UNSHIELD_API bool unshield_file_save (Unshield* unshield, int in
UNSHIELD_API int unshield_file_directory (Unshield* unshield, int index);
UNSHIELD_API size_t unshield_file_size (Unshield* unshield, int index);
UNSHIELD_API bool unshield_file_iso_date (Unshield* unshield, int index, char* buf, size_t size);
UNSHIELD_API time_t unshield_file_timestamp (Unshield* unshield, int index);

/** For investigation of compressed data */
UNSHIELD_API bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename);
Expand Down
7 changes: 5 additions & 2 deletions man/unshield.1
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.TH UNSHIELD "1" "November 2023" "The Unshield project" "https://github.com/twogood/unshield"
.TH UNSHIELD "1" "December 2024" "The Unshield project" "https://github.com/twogood/unshield"
.SH NAME
unshield \- extract CAB files from an InstallShield installer archive
.SH SYNOPSIS
unshield [\-c COMPONENT] [\-d DIRECTORY] [\-D LEVEL] [\-g GROUP] [\-h] [\-i VERSION] [\-e ENCODING] [\-j] [\-L] [\-O] [\-r] [\-R] [\-V] c|g|l|t|x CABFILE [FILENAME...]
unshield [\-c COMPONENT] [\-d DIRECTORY] [\-D LEVEL] [\-g GROUP] [\-h] [\-i VERSION] [\-e ENCODING] [\-j] [\-L] [\-O] [\-r] [\-R] [\-t] [\-V] c|g|l|t|x CABFILE [FILENAME...]
.SH DESCRIPTION
Unshield extracts CAB files from InstallShield installers, used to
install software on Microsoft Windows based machines.
Expand Down Expand Up @@ -50,6 +50,9 @@ Save raw data (do not decompress)
\fB\-R\fR
Don't do any conversion to file and directory names when extracting
.TP
\fB-t\fR
Set the modification date/time from the metadata when extracting
.TP
\fB\-V\fR, \fB\-\-version\fR
Print version information
.SS "Commands:"
Expand Down
23 changes: 21 additions & 2 deletions src/unshield.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <utime.h>
#include <getopt.h>
#include "../lib/libunshield.h"
#ifdef HAVE_CONFIG_H
Expand Down Expand Up @@ -68,6 +69,7 @@ static const char* component_name = NULL;
static bool junk_paths = false;
static bool make_lowercase = false;
static bool raw_filename = false;
static bool set_timestamp = false;
static ACTION action = ACTION_EXTRACT;
static int log_level = UNSHIELD_LOG_LEVEL_LOWEST;
static int exit_status = 0;
Expand Down Expand Up @@ -192,7 +194,7 @@ static void show_usage(const char* name)
fprintf(stderr,
"Syntax:\n"
"\n"
"\t%s [-c COMPONENT] [-d DIRECTORY] [-D LEVEL] [-g GROUP] [-h] [-i VERSION] [-e ENCODING] [-j] [-L] [-O] [-r] [-R] [-V] c|g|l|t|x CABFILE [FILENAME...]\n"
"\t%s [-c COMPONENT] [-d DIRECTORY] [-D LEVEL] [-g GROUP] [-h] [-i VERSION] [-e ENCODING] [-j] [-L] [-O] [-r] [-R] [-t] [-V] c|g|l|t|x CABFILE [FILENAME...]\n"
"\n"
"Options:\n"
"\t-c COMPONENT Only list/extract this component\n"
Expand All @@ -211,6 +213,7 @@ static void show_usage(const char* name)
"\t-O Use old compression\n"
"\t-r Save raw data (do not decompress)\n"
"\t-R Don't do any conversion to file and directory names when extracting\n"
"\t-t Set the modification date/time from the metadata when extracting\n"
"\t-V --version Print copyright and version information\n"
"\n"
"Commands:\n"
Expand Down Expand Up @@ -243,7 +246,7 @@ static bool handle_parameters(
{ NULL, 0, NULL, 0 }
};

while ((c = getopt_long(argc, argv, "c:d:D:g:hi:e:jLOrRV", long_options, NULL)) != -1)
while ((c = getopt_long(argc, argv, "c:d:D:g:hi:e:jLOrRtV", long_options, NULL)) != -1)
{
switch (c)
{
Expand Down Expand Up @@ -297,6 +300,10 @@ static bool handle_parameters(
format = FORMAT_RAW;
break;

case 't':
set_timestamp = true;
break;

case 'V':
printf("Unshield version " VERSION ". MIT License. (C) 2003-2023 David Eriksson.\n");
exit(0);
Expand Down Expand Up @@ -540,6 +547,18 @@ static bool extract_file(Unshield* unshield, const char* prefix, int index)
break;
}

if (success && set_timestamp)
{
/* XXX: Use file function wrappers? */
struct utimbuf utim;
struct stat info;

stat(filename, &info);
utim.actime = info.st_atim.tv_sec;
utim.modtime = unshield_file_timestamp(unshield, index);
utime(filename, &utim);
}

exit:
if (!success)
{
Expand Down

0 comments on commit 90b2a52

Please sign in to comment.