Skip to content

Commit

Permalink
Print modification date in file listings
Browse files Browse the repository at this point in the history
This also adds a helper function to load the DOS date/time into a tm
structure and an library function to get the ISO 8601 date
  • Loading branch information
TheComputerGuy96 committed Dec 14, 2024
1 parent 968a50f commit a70ab03
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 3 deletions.
24 changes: 24 additions & 0 deletions lib/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,30 @@ size_t unshield_file_size(Unshield* unshield, int index)/*{{{*/
return 0;
}/*}}}*/

/* This uses the ISO 8601 date format (except for milliseconds) */
bool unshield_file_iso_date (Unshield* unshield, int index, char* buf, size_t size)/*{{{*/
{
FileDescriptor* fd = unshield_get_file_descriptor(unshield, index);
struct tm date;

if (size < 32)
{
unshield_error("Buffer size %" SIZE_FORMAT " is too small", size);
return false;
}

if (fd)
unshield_dos_to_tm(fd->dos_date, fd->dos_time, &date);
else
{
unshield_warning("Failed to get file descriptor %i", index);
memset(&date, 0, sizeof(date));
}

(void)strftime(buf, size, "%Y-%m-%d %H:%M:%S", &date);
return fd ? true : false;
}/*}}}*/

bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename)
{
/* XXX: Thou Shalt Not Cut & Paste... */
Expand Down
22 changes: 22 additions & 0 deletions lib/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,26 @@ const char* unshield_header_get_string(Header* header, uint32_t offset)
return unshield_get_utf8_string(header, unshield_header_get_buffer(header, offset));
}

/**
Based on MIT Wine code and DosDateTimeToFileTime() MSDN documentation
*/
void unshield_dos_to_tm(uint16_t dos_date, uint16_t dos_time, struct tm* tm)
{
memset(tm, 0, sizeof(*tm));

if (dos_date)
{
tm->tm_year = (dos_date >> 9) + 80;
tm->tm_mon = ((dos_date >> 5) & 0x0f) - 1;
tm->tm_mday = dos_date & 0x1f;
}

if (dos_time)
{
tm->tm_hour = dos_time >> 11;
tm->tm_min = (dos_time >> 5) & 0x3f;
tm->tm_sec = (dos_time & 0x1f) * 2;
}
}


2 changes: 2 additions & 0 deletions lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ const char* unshield_header_get_string(Header* header, uint32_t offset);
uint8_t* unshield_header_get_buffer(Header* header, uint32_t offset);
char *unshield_get_last_path_separator(char *path);

void unshield_dos_to_tm(uint16_t dos_date, uint16_t dos_time, struct tm* tm);

static inline void* unshield_fopen(Unshield* unshield, const char *filename, const char *modes)
{
return unshield->io_callbacks->fopen(filename, modes, unshield->io_userdata);
Expand Down
2 changes: 2 additions & 0 deletions lib/libunshield.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <stdbool.h>
#include <stddef.h>
#include <time.h>

#define UNSHIELD_LOG_LEVEL_LOWEST 0

Expand Down Expand Up @@ -108,6 +109,7 @@ UNSHIELD_API bool unshield_file_is_valid (Unshield* unshield, int in
UNSHIELD_API bool unshield_file_save (Unshield* unshield, int index, const char* filename);
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);

/** For investigation of compressed data */
UNSHIELD_API bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename);
Expand Down
10 changes: 7 additions & 3 deletions src/unshield.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,11 +683,14 @@ static int list_files_helper(Unshield* unshield, const char* prefix, int first,
for (i = first; i <= last; i++)
{
char dirname[4096];
char date[32];

if (unshield_file_is_valid(unshield, i) && should_process_file(unshield, i))
{
valid_count++;

(void)unshield_file_iso_date(unshield, i, date, sizeof(date));

if (prefix && prefix[0])
{
strcpy(dirname, prefix);
Expand All @@ -708,10 +711,11 @@ static int list_files_helper(Unshield* unshield, const char* prefix, int first,
if (dirname[strlen(dirname)-1] != '\\')
strcat(dirname, "\\");

printf(" %8" SIZE_FORMAT " %s%s\n",
printf(" %8" SIZE_FORMAT " %s %s%s\n",
unshield_file_size(unshield, i),
date,
dirname,
unshield_file_name(unshield, i));
unshield_file_name(unshield, i));
}
}

Expand Down Expand Up @@ -748,7 +752,7 @@ static bool do_action(Unshield* unshield, ActionHelper helper)
}
}

printf(" -------- -------\n %i files\n", count);
printf(" -------- ------------------- -------\n %i files\n", count);

return true;
}
Expand Down

0 comments on commit a70ab03

Please sign in to comment.