summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristos Zoulas <christos@zoulas.com>2021-10-24 15:52:18 +0000
committerChristos Zoulas <christos@zoulas.com>2021-10-24 15:52:18 +0000
commit7d40be887147acbb055997616c6e6da99b4efd5f (patch)
tree50a74d82983521837b244556c65db9f3cf0e807f
parentf0db2dfd99bbd61552225bbe6aa3ddbcdf6a5148 (diff)
downloadfile-git-7d40be887147acbb055997616c6e6da99b4efd5f.tar.gz
Add support for msdos dates and times
-rw-r--r--ChangeLog4
-rw-r--r--src/apprentice.c32
-rw-r--r--src/file.h122
-rw-r--r--src/print.c69
-rw-r--r--src/softmagic.c47
5 files changed, 203 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 0be9711b..0a972147 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2021-10-24 11:51 Christos Zoulas <christos@zoulas.com>
+
+ * Add support for msdos dates and times
+
2021-10-20 9:55 Christos Zoulas <christos@zoulas.com>
* use the system byte swapping functions if available (Werner Fink)
diff --git a/src/apprentice.c b/src/apprentice.c
index 98ce1801..7eb57f1f 100644
--- a/src/apprentice.c
+++ b/src/apprentice.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.311 2021/10/21 13:00:25 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.312 2021/10/24 15:52:18 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -288,6 +288,12 @@ static const struct type_tbl_s type_tbl[] = {
{ XX("offset"), FILE_OFFSET, FILE_FMT_QUAD },
{ XX("bevarint"), FILE_BEVARINT, FILE_FMT_STR },
{ XX("levarint"), FILE_LEVARINT, FILE_FMT_STR },
+ { XX("msdosdate"), FILE_MSDOSDATE, FILE_FMT_STR },
+ { XX("lemsdosdate"), FILE_LEMSDOSDATE, FILE_FMT_STR },
+ { XX("bemsdosdate"), FILE_BEMSDOSDATE, FILE_FMT_STR },
+ { XX("msdostime"), FILE_MSDOSTIME, FILE_FMT_STR },
+ { XX("lemsdostime"), FILE_LEMSDOSTIME, FILE_FMT_STR },
+ { XX("bemsdostime"), FILE_BEMSDOSTIME, FILE_FMT_STR },
{ XX_NULL, FILE_INVALID, FILE_FMT_NONE },
};
@@ -835,6 +841,12 @@ typesize(int type)
case FILE_SHORT:
case FILE_LESHORT:
case FILE_BESHORT:
+ case FILE_MSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_BEMSDOSTIME:
+ case FILE_LEMSDOSTIME:
return 2;
case FILE_LONG:
@@ -938,6 +950,12 @@ apprentice_magic_strength(const struct magic *m)
case FILE_LEVARINT:
case FILE_GUID:
case FILE_OFFSET:
+ case FILE_MSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_BEMSDOSTIME:
+ case FILE_LEMSDOSTIME:
ts = typesize(m->type);
if (ts == FILE_BADSIZE)
abort();
@@ -1134,6 +1152,12 @@ set_test_type(struct magic *mstart, struct magic *m)
case FILE_DER:
case FILE_GUID:
case FILE_OFFSET:
+ case FILE_MSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_BEMSDOSTIME:
+ case FILE_LEMSDOSTIME:
mstart->flag |= BINTEST;
break;
case FILE_STRING:
@@ -1553,6 +1577,12 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_FLOAT:
case FILE_BEFLOAT:
case FILE_LEFLOAT:
+ case FILE_MSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_BEMSDOSTIME:
+ case FILE_LEMSDOSTIME:
v = CAST(int32_t, v);
break;
case FILE_QUAD:
diff --git a/src/file.h b/src/file.h
index 28a05e17..f04f7c4b 100644
--- a/src/file.h
+++ b/src/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.227 2021/06/30 10:08:48 christos Exp $
+ * @(#)$File: file.h,v 1.228 2021/10/24 15:52:18 christos Exp $
*/
#ifndef __file_h__
@@ -157,7 +157,7 @@
#define MAXstring 128 /* max len of "string" types */
#define MAGICNO 0xF11E041C
-#define VERSIONNO 16
+#define VERSIONNO 17
#define FILE_MAGICSIZE 376
#define FILE_GUID_SIZE sizeof("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
@@ -213,60 +213,66 @@ struct magic {
uint8_t vallen; /* length of string value, if any */
uint8_t type; /* comparison type (FILE_*) */
uint8_t in_type; /* type of indirection */
-#define FILE_INVALID 0
-#define FILE_BYTE 1
-#define FILE_SHORT 2
-#define FILE_DEFAULT 3
-#define FILE_LONG 4
-#define FILE_STRING 5
-#define FILE_DATE 6
-#define FILE_BESHORT 7
-#define FILE_BELONG 8
-#define FILE_BEDATE 9
-#define FILE_LESHORT 10
-#define FILE_LELONG 11
-#define FILE_LEDATE 12
-#define FILE_PSTRING 13
-#define FILE_LDATE 14
-#define FILE_BELDATE 15
-#define FILE_LELDATE 16
-#define FILE_REGEX 17
-#define FILE_BESTRING16 18
-#define FILE_LESTRING16 19
-#define FILE_SEARCH 20
-#define FILE_MEDATE 21
-#define FILE_MELDATE 22
-#define FILE_MELONG 23
-#define FILE_QUAD 24
-#define FILE_LEQUAD 25
-#define FILE_BEQUAD 26
-#define FILE_QDATE 27
-#define FILE_LEQDATE 28
-#define FILE_BEQDATE 29
-#define FILE_QLDATE 30
-#define FILE_LEQLDATE 31
-#define FILE_BEQLDATE 32
-#define FILE_FLOAT 33
-#define FILE_BEFLOAT 34
-#define FILE_LEFLOAT 35
-#define FILE_DOUBLE 36
-#define FILE_BEDOUBLE 37
-#define FILE_LEDOUBLE 38
-#define FILE_BEID3 39
-#define FILE_LEID3 40
-#define FILE_INDIRECT 41
-#define FILE_QWDATE 42
-#define FILE_LEQWDATE 43
-#define FILE_BEQWDATE 44
-#define FILE_NAME 45
-#define FILE_USE 46
-#define FILE_CLEAR 47
-#define FILE_DER 48
-#define FILE_GUID 49
-#define FILE_OFFSET 50
-#define FILE_BEVARINT 51
-#define FILE_LEVARINT 52
-#define FILE_NAMES_SIZE 53 /* size of array to contain all names */
+#define FILE_INVALID 0
+#define FILE_BYTE 1
+#define FILE_SHORT 2
+#define FILE_DEFAULT 3
+#define FILE_LONG 4
+#define FILE_STRING 5
+#define FILE_DATE 6
+#define FILE_BESHORT 7
+#define FILE_BELONG 8
+#define FILE_BEDATE 9
+#define FILE_LESHORT 10
+#define FILE_LELONG 11
+#define FILE_LEDATE 12
+#define FILE_PSTRING 13
+#define FILE_LDATE 14
+#define FILE_BELDATE 15
+#define FILE_LELDATE 16
+#define FILE_REGEX 17
+#define FILE_BESTRING16 18
+#define FILE_LESTRING16 19
+#define FILE_SEARCH 20
+#define FILE_MEDATE 21
+#define FILE_MELDATE 22
+#define FILE_MELONG 23
+#define FILE_QUAD 24
+#define FILE_LEQUAD 25
+#define FILE_BEQUAD 26
+#define FILE_QDATE 27
+#define FILE_LEQDATE 28
+#define FILE_BEQDATE 29
+#define FILE_QLDATE 30
+#define FILE_LEQLDATE 31
+#define FILE_BEQLDATE 32
+#define FILE_FLOAT 33
+#define FILE_BEFLOAT 34
+#define FILE_LEFLOAT 35
+#define FILE_DOUBLE 36
+#define FILE_BEDOUBLE 37
+#define FILE_LEDOUBLE 38
+#define FILE_BEID3 39
+#define FILE_LEID3 40
+#define FILE_INDIRECT 41
+#define FILE_QWDATE 42
+#define FILE_LEQWDATE 43
+#define FILE_BEQWDATE 44
+#define FILE_NAME 45
+#define FILE_USE 46
+#define FILE_CLEAR 47
+#define FILE_DER 48
+#define FILE_GUID 49
+#define FILE_OFFSET 50
+#define FILE_BEVARINT 51
+#define FILE_LEVARINT 52
+#define FILE_MSDOSDATE 53
+#define FILE_LEMSDOSDATE 54
+#define FILE_BEMSDOSDATE 55
+#define FILE_MSDOSTIME 56
+#define FILE_LEMSDOSTIME 57
+#define FILE_BEMSDOSTIME 58
+#define FILE_NAMES_SIZE 59 /* size of array to contain all names */
#define IS_STRING(t) \
((t) == FILE_STRING || \
@@ -485,7 +491,9 @@ typedef unsigned long file_unichar_t;
struct stat;
#define FILE_T_LOCAL 1
#define FILE_T_WINDOWS 2
-protected const char *file_fmttime(char *, size_t, uint64_t, int);
+protected const char *file_fmtdatetime(char *, size_t, uint64_t, int);
+protected const char *file_fmtdate(char *, size_t, uint16_t);
+protected const char *file_fmttime(char *, size_t, uint16_t);
protected const char *file_fmtvarint(const unsigned char *, int, char *,
size_t);
protected struct magic_set *file_ms_alloc(int);
diff --git a/src/print.c b/src/print.c
index 6d9816ad..ee8cb5af 100644
--- a/src/print.c
+++ b/src/print.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.89 2021/06/30 10:08:48 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.90 2021/10/24 15:52:18 christos Exp $")
#endif /* lint */
#include <string.h>
@@ -157,34 +157,34 @@ file_mdump(struct magic *m)
case FILE_BEDATE:
case FILE_MEDATE:
(void)fprintf(stderr, "%s,",
- file_fmttime(tbuf, sizeof(tbuf), m->value.l, 0));
+ file_fmtdatetime(tbuf, sizeof(tbuf), m->value.l, 0));
break;
case FILE_LDATE:
case FILE_LELDATE:
case FILE_BELDATE:
case FILE_MELDATE:
(void)fprintf(stderr, "%s,",
- file_fmttime(tbuf, sizeof(tbuf), m->value.l,
+ file_fmtdatetime(tbuf, sizeof(tbuf), m->value.l,
FILE_T_LOCAL));
break;
case FILE_QDATE:
case FILE_LEQDATE:
case FILE_BEQDATE:
(void)fprintf(stderr, "%s,",
- file_fmttime(tbuf, sizeof(tbuf), m->value.q, 0));
+ file_fmtdatetime(tbuf, sizeof(tbuf), m->value.q, 0));
break;
case FILE_QLDATE:
case FILE_LEQLDATE:
case FILE_BEQLDATE:
(void)fprintf(stderr, "%s,",
- file_fmttime(tbuf, sizeof(tbuf), m->value.q,
+ file_fmtdatetime(tbuf, sizeof(tbuf), m->value.q,
FILE_T_LOCAL));
break;
case FILE_QWDATE:
case FILE_LEQWDATE:
case FILE_BEQWDATE:
(void)fprintf(stderr, "%s,",
- file_fmttime(tbuf, sizeof(tbuf), m->value.q,
+ file_fmtdatetime(tbuf, sizeof(tbuf), m->value.q,
FILE_T_WINDOWS));
break;
case FILE_FLOAT:
@@ -202,6 +202,18 @@ file_mdump(struct magic *m)
(void)fprintf(stderr, "%s", file_fmtvarint(
m->value.us, m->type, tbuf, sizeof(tbuf)));
break;
+ case FILE_MSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ (void)fprintf(stderr, "%s,",
+ file_fmtdate(tbuf, sizeof(tbuf), m->value.h));
+ break;
+ case FILE_MSDOSTIME:
+ case FILE_BEMSDOSTIME:
+ case FILE_LEMSDOSTIME:
+ (void)fprintf(stderr, "%s,",
+ file_fmttime(tbuf, sizeof(tbuf), m->value.h));
+ break;
case FILE_DEFAULT:
/* XXX - do anything here? */
break;
@@ -252,7 +264,7 @@ file_fmtvarint(const unsigned char *us, int t, char *buf, size_t blen)
}
protected const char *
-file_fmttime(char *buf, size_t bsize, uint64_t v, int flags)
+file_fmtdatetime(char *buf, size_t bsize, uint64_t v, int flags)
{
char *pp;
time_t t;
@@ -282,6 +294,49 @@ file_fmttime(char *buf, size_t bsize, uint64_t v, int flags)
pp[strcspn(pp, "\n")] = '\0';
return pp;
out:
+ strlcpy(buf, "*Invalid datetime*", bsize);
+ return buf;
+}
+
+/*
+ * https://docs.microsoft.com/en-us/windows/win32/api/winbase/\
+ * nf-winbase-dosdatetimetofiletime?redirectedfrom=MSDN
+ */
+protected const char *
+file_fmtdate(char *buf, size_t bsize, uint16_t v)
+{
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_mday = v & 0x1f;
+ tm.tm_mon = ((v >> 5) & 0xf) - 1;
+ tm.tm_year = (v >> 9) + 80;
+
+ if (strftime(buf, bsize, "%a, %b %d %Y", &tm) == 0)
+ goto out;
+
+ return buf;
+out:
+ strlcpy(buf, "*Invalid date*", bsize);
+ return buf;
+}
+
+protected const char *
+file_fmttime(char *buf, size_t bsize, uint16_t v)
+{
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_sec = (v & 0x1f) * 2;
+ tm.tm_min = ((v >> 5) & 0x3f);
+ tm.tm_hour = (v >> 11);
+
+ if (strftime(buf, bsize, "%T", &tm) == 0)
+ goto out;
+
+ return buf;
+out:
strlcpy(buf, "*Invalid time*", bsize);
return buf;
+
}
diff --git a/src/softmagic.c b/src/softmagic.c
index 8d2d7b72..7c0e762d 100644
--- a/src/softmagic.c
+++ b/src/softmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.315 2021/09/03 13:17:52 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.316 2021/10/24 15:52:18 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -675,7 +675,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_LEDATE:
case FILE_MEDATE:
if (file_printf(ms, F(ms, desc, "%s"),
- file_fmttime(tbuf, sizeof(tbuf), p->l, 0)) == -1)
+ file_fmtdatetime(tbuf, sizeof(tbuf), p->l, 0)) == -1)
return -1;
t = ms->offset + sizeof(uint32_t);
break;
@@ -685,7 +685,8 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_LELDATE:
case FILE_MELDATE:
if (file_printf(ms, F(ms, desc, "%s"),
- file_fmttime(tbuf, sizeof(tbuf), p->l, FILE_T_LOCAL)) == -1)
+ file_fmtdatetime(tbuf, sizeof(tbuf), p->l, FILE_T_LOCAL))
+ == -1)
return -1;
t = ms->offset + sizeof(uint32_t);
break;
@@ -694,7 +695,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQDATE:
case FILE_LEQDATE:
if (file_printf(ms, F(ms, desc, "%s"),
- file_fmttime(tbuf, sizeof(tbuf), p->q, 0)) == -1)
+ file_fmtdatetime(tbuf, sizeof(tbuf), p->q, 0)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
@@ -703,7 +704,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQLDATE:
case FILE_LEQLDATE:
if (file_printf(ms, F(ms, desc, "%s"),
- file_fmttime(tbuf, sizeof(tbuf), p->q, FILE_T_LOCAL)) == -1)
+ file_fmtdatetime(tbuf, sizeof(tbuf), p->q, FILE_T_LOCAL)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
@@ -712,7 +713,7 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEQWDATE:
case FILE_LEQWDATE:
if (file_printf(ms, F(ms, desc, "%s"),
- file_fmttime(tbuf, sizeof(tbuf), p->q, FILE_T_WINDOWS))
+ file_fmtdatetime(tbuf, sizeof(tbuf), p->q, FILE_T_WINDOWS))
== -1)
return -1;
t = ms->offset + sizeof(uint64_t);
@@ -810,6 +811,22 @@ mprint(struct magic_set *ms, struct magic *m)
return -1;
t = ms->offset;
break;
+ case FILE_MSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ if (file_printf(ms, F(ms, desc, "%s"),
+ file_fmtdate(tbuf, sizeof(tbuf), p->h)) == -1)
+ return -1;
+ t = ms->offset + sizeof(uint16_t);
+ break;
+ case FILE_MSDOSTIME:
+ case FILE_BEMSDOSTIME:
+ case FILE_LEMSDOSTIME:
+ if (file_printf(ms, F(ms, desc, "%s"),
+ file_fmttime(tbuf, sizeof(tbuf), p->h)) == -1)
+ return -1;
+ t = ms->offset + sizeof(uint16_t);
+ break;
default:
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
return -1;
@@ -832,6 +849,12 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
+ case FILE_MSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_LEMSDOSTIME:
+ case FILE_BEMSDOSTIME:
o = CAST(int32_t, (ms->offset + sizeof(short)));
break;
@@ -1137,6 +1160,12 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
goto out;
return 1;
case FILE_SHORT:
+ case FILE_MSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_LEMSDOSTIME:
+ case FILE_BEMSDOSTIME:
if (cvt_16(p, m) == -1)
goto out;
return 1;
@@ -2016,6 +2045,12 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
+ case FILE_MSDOSDATE:
+ case FILE_LEMSDOSDATE:
+ case FILE_BEMSDOSDATE:
+ case FILE_MSDOSTIME:
+ case FILE_LEMSDOSTIME:
+ case FILE_BEMSDOSTIME:
v = p->h;
break;