diff options
author | Christos Zoulas <christos@zoulas.com> | 2021-10-24 15:52:18 +0000 |
---|---|---|
committer | Christos Zoulas <christos@zoulas.com> | 2021-10-24 15:52:18 +0000 |
commit | 7d40be887147acbb055997616c6e6da99b4efd5f (patch) | |
tree | 50a74d82983521837b244556c65db9f3cf0e807f | |
parent | f0db2dfd99bbd61552225bbe6aa3ddbcdf6a5148 (diff) | |
download | file-git-7d40be887147acbb055997616c6e6da99b4efd5f.tar.gz |
Add support for msdos dates and times
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/apprentice.c | 32 | ||||
-rw-r--r-- | src/file.h | 122 | ||||
-rw-r--r-- | src/print.c | 69 | ||||
-rw-r--r-- | src/softmagic.c | 47 |
5 files changed, 203 insertions, 71 deletions
@@ -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: @@ -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; |