aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-11-29 01:02:02 -0500
committerB. Watson <urchlay@slackware.uk>2025-11-29 01:02:02 -0500
commit3340301b02ae647cdb286112c32772bda0faf503 (patch)
tree6847f4f17dee95c5801e3e80607f2c1f6c1f983c /src
parent0861fc6fc6614084bad79db36eeae4eefd75ff9e (diff)
downloadalftools-3340301b02ae647cdb286112c32772bda0faf503.tar.gz
unalf: actually use timestamps from the alf header (and add -T option to not use them).
Diffstat (limited to 'src')
-rw-r--r--src/alf.18
-rw-r--r--src/alf.c3
-rw-r--r--src/alf.rst6
-rw-r--r--src/extract.c34
-rw-r--r--src/opts.c3
-rw-r--r--src/unalf.118
-rw-r--r--src/unalf.h1
-rw-r--r--src/unalf.rst12
8 files changed, 70 insertions, 15 deletions
diff --git a/src/alf.1 b/src/alf.1
index 1030589..87d0a36 100644
--- a/src/alf.1
+++ b/src/alf.1
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
-.TH "ALF" 1 "2025-11-28" "0.2.0" "Urchlay's Atari 8-bit Tools"
+.TH "ALF" 1 "2025-11-29" "0.2.0" "Urchlay's Atari 8-bit Tools"
.SH NAME
alf \- create Atari 8-bit ALF archives
.\" RST source for alf(1) man page. Convert with:
@@ -151,6 +151,12 @@ systems, so there\(aqs no option for that.
Note that \fBalf\fP is a complete reverse\-engineered rewrite in C, \fInot\fP
a port of the original 6502 code as \fBunalf\fP is. It\(aqs still being
tested, and may still contain bugs.
+.sp
+A note about the Atari filenames: \fBDZ.COM\fP is sometimes found on
+old disk images as \fBUNALF.COM\fP, and \fBLZ.COM\fP is sometimes called
+\fBALF.COM\fP or \fBALFER.COM\fP\&. I\(aqve used the original names partly
+out of respect for the original author, and partly to avoid confusion
+between my \fBalf\fP/\fBunalf\fP and his Atari ones.
.SS File Size Limits
.sp
\fBalf\fP (and \fBLZ.COM\fP) have a 16MB file size limit. \fBuanlf\fP
diff --git a/src/alf.c b/src/alf.c
index 49e69c2..88cb316 100644
--- a/src/alf.c
+++ b/src/alf.c
@@ -143,7 +143,8 @@ unsigned long get_msdos_date_time(void) {
msdos_year = tm->tm_year + 1900 - 1980;
- ms_date = tm->tm_mday | (tm->tm_mon << 5) | (msdos_year << 9);
+ /* tm_mon + 1 because MS uses 1-12 for months, and struct tm uses 0-11 */
+ ms_date = (tm->tm_mday) | (((tm->tm_mon + 1) << 5)) | (msdos_year << 9);
ms_time = (tm->tm_sec >> 1) | (tm->tm_min << 5) | (tm->tm_hour << 11);
return ms_date | (ms_time << 16);
}
diff --git a/src/alf.rst b/src/alf.rst
index 3110180..4b011aa 100644
--- a/src/alf.rst
+++ b/src/alf.rst
@@ -127,6 +127,12 @@ Note that **alf** is a complete reverse-engineered rewrite in C, *not*
a port of the original 6502 code as **unalf** is. It's still being
tested, and may still contain bugs.
+A note about the Atari filenames: **DZ.COM** is sometimes found on
+old disk images as **UNALF.COM**, and **LZ.COM** is sometimes called
+**ALF.COM** or **ALFER.COM**. I've used the original names partly
+out of respect for the original author, and partly to avoid confusion
+between my **alf**\/**unalf** and his Atari ones.
+
File Size Limits
----------------
diff --git a/src/extract.c b/src/extract.c
index 305cd4a..6d940a2 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -1,5 +1,7 @@
#include "unalf.h"
#include "addrs.h"
+#include <time.h>
+#include <utime.h>
int bad_checksum, bad_checksum_count = 0;
int new_file = 0;
@@ -101,6 +103,32 @@ void fix_filename(void) {
}
}
+void set_datetime() {
+ u16 t, d;
+ struct tm tm;
+ time_t time;
+ struct utimbuf utb;
+
+ t = dpeek(alf_hdr_time0);
+ d = dpeek(alf_hdr_date0);
+
+ tm.tm_sec = (t & 0x1f) << 1;
+ tm.tm_hour = t >> 11;
+ if(tm.tm_hour == 24) tm.tm_hour = 0;
+ tm.tm_min = (t >> 5) & 0x3f;
+
+ tm.tm_year = (d >> 9) + 1980 - 1900;
+ tm.tm_mon = ((d >> 5) & 0x0f) - 1;
+ tm.tm_mday = (d & 0x1f);
+
+ time = mktime(&tm);
+
+ if(time != (time_t) -1) {
+ utb.actime = utb.modtime = time;
+ utime(out_filename, &utb); /* ignore errors */
+ }
+}
+
void make_backup(void) {
/* up to 12-char FILENAME.EXT, plus a ~, plus null terminator = 14 */
char backup[14];
@@ -162,7 +190,11 @@ void extract_alf(void) {
fprintf(stderr, "%s: %s should be %u bytes, but extracted to %u.\n",
self, out_filename, getquad(alf_hdr_origsize0), bytes_written);
- if(!opts.extract_to_stdout) fclose(out_file);
+ if(!opts.extract_to_stdout) {
+ fclose(out_file);
+ if(!opts.ignore_datetime)
+ set_datetime();
+ }
out_filename = 0;
}
diff --git a/src/opts.c b/src/opts.c
index 416163c..aca6e83 100644
--- a/src/opts.c
+++ b/src/opts.c
@@ -1,6 +1,6 @@
#include "unalf.h"
-#define OPTIONS "aefklLopqtvVd:x:"
+#define OPTIONS "aefklLopqtTvVd:x:"
/* uncomment to test exclude/include glob lists */
// #define DEBUG_GLOBS
@@ -44,6 +44,7 @@ void parse_opts(int argc, char * const *argv) {
case 'p': opts.extract_to_stdout++; opts.quiet++; break;
case 'q': opts.quiet++; break;
case 't': opts.testonly++; opts.listonly = 0; break;
+ case 'T': opts.ignore_datetime = 1; break;
case 'v': opts.listonly = 1; opts.testonly = 0; opts.verbose_list++; break;
case 'V': puts(VERSION); exit(0); break;
case 'd': opts.outdir = optarg; break;
diff --git a/src/unalf.1 b/src/unalf.1
index a8149c5..3306279 100644
--- a/src/unalf.1
+++ b/src/unalf.1
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
-.TH "UNALF" 1 "2025-11-28" "0.2.0" "Urchlay's Atari 8-bit Tools"
+.TH "UNALF" 1 "2025-11-29" "0.2.0" "Urchlay's Atari 8-bit Tools"
.SH NAME
unalf \- extract Atari 8-bit ALF archives
.\" RST source for unalf(1) man page. Convert with:
@@ -187,13 +187,18 @@ anywhere.
.
.INDENT 0.0
.TP
+.B \-T
+Ignore timestamps in \fIalf\-file\fP, when extracting. Normally the extracted files
+have their \fBmtime\fP set to the time saved in the archive. With \fB\-T\fP, the
+extracted files will have \fBmtime\fP set to the current time.
+.TP
.B \-v
Verbose listing of archive contents, with compressed and original
sizes, compression ration, date/time stamps, and checksum. The
output format is similar to that of \fBarc \-v\fP, minus the \fIStowage\fP
column, since \fIALF\fP doesn\(aqt support multiple compression types. The
date and time are displayed, but in most .alf files these are the
-default values of "8 Jan 82 12:24a".
+default values of "8 Jan 82 12:24:38a".
.sp
Unlike \fB\-l\fP, the \fB\-v\fP listing shows the filenames exactly as
stored in the archive (ignores \fB\-L\fP, enables \fB\-k\fP), and always
@@ -357,17 +362,16 @@ to standard output and text file EOL conversion.
.IP \(bu 2
Turning the screen off for speed makes no sense on modern operating
systems, so there\(aqs no option for that.
+.IP \(bu 2
+The timestamps saved in the archive are actually used to set the
+date/time of the extracted files (though this can be disabled with \fB\-T\fP).
.UNINDENT
.sp
-Neither this \fBunalf\fP nor \fBDZ.COM\fP actually use the dates/times
-stored in the archive. Extracted files will have their timestamps set
-to the current date/time.
-.sp
A note about the Atari filenames: \fBDZ.COM\fP is sometimes found on
old disk images as \fBUNALF.COM\fP, and \fBLZ.COM\fP is sometimes called
\fBALF.COM\fP or \fBALFER.COM\fP\&. I\(aqve used the original names partly
out of respect for the original author, and partly to avoid confusion
-between my \fBunalf\fP and the Atari one.
+between my \fBalf\fP/\fBunalf\fP and his Atari ones.
.SH BUGS
.sp
A minor one: \fBunalf\fP can\(aqt correctly extract files larger than about
diff --git a/src/unalf.h b/src/unalf.h
index 743282d..2d0072e 100644
--- a/src/unalf.h
+++ b/src/unalf.h
@@ -83,6 +83,7 @@ typedef struct {
int quiet;
int verbose_list;
int fixjunk;
+ int ignore_datetime;
} opts_t;
#define MAX_EXCLUDES 256
diff --git a/src/unalf.rst b/src/unalf.rst
index 1c04c3b..c43d8d4 100644
--- a/src/unalf.rst
+++ b/src/unalf.rst
@@ -149,6 +149,11 @@ OPTIONS
.. test archive.
+-T
+ Ignore timestamps in *alf-file*, when extracting. Normally the extracted files
+ have their **mtime** set to the time saved in the archive. With **-T**, the
+ extracted files will have **mtime** set to the current time.
+
-v
Verbose listing of archive contents, with compressed and original
sizes, compression ration, date/time stamps, and checksum. The
@@ -312,15 +317,14 @@ aka **UNALF.COM**, with the following differences:
- Turning the screen off for speed makes no sense on modern operating
systems, so there's no option for that.
-Neither this **unalf** nor **DZ.COM** actually use the dates/times
-stored in the archive. Extracted files will have their timestamps set
-to the current date/time.
+- The timestamps saved in the archive are actually used to set the
+ date/time of the extracted files (though this can be disabled with **-T**).
A note about the Atari filenames: **DZ.COM** is sometimes found on
old disk images as **UNALF.COM**, and **LZ.COM** is sometimes called
**ALF.COM** or **ALFER.COM**. I've used the original names partly
out of respect for the original author, and partly to avoid confusion
-between my **unalf** and the Atari one.
+between my **alf**\/**unalf** and his Atari ones.
BUGS
====