aboutsummaryrefslogtreecommitdiffstats
path: root/src/launcherutil.c
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2024-01-11 00:39:56 -0600
committerLibravatar bigfoot547 <[email protected]>2024-01-11 00:39:56 -0600
commitb837ef02aff4c0974161ff2e077551a9710fdac5 (patch)
tree3ae0af26264f2ec62af5ebf4391ef6399f67354f /src/launcherutil.c
parentactually use runtime (diff)
add auth
Diffstat (limited to 'src/launcherutil.c')
-rw-r--r--src/launcherutil.c135
1 files changed, 130 insertions, 5 deletions
diff --git a/src/launcherutil.c b/src/launcherutil.c
index 4a866f5..11d5e00 100644
--- a/src/launcherutil.c
+++ b/src/launcherutil.c
@@ -252,11 +252,6 @@ int l2_launcher_mkdir_parents_ex(const char *path, unsigned ignore)
return 0;
}
-char *l2_launcher_parse_iso_time(const char *str, struct tm *ts)
-{
- return strptime(str, "%FT%T%z", ts); /* TODO: replace with something portable */
-}
-
void l2_launcher_download_init(struct l2_dlbuf *buf)
{
buf->data = NULL;
@@ -655,3 +650,133 @@ int l2_launcher_ftw(const char *path, int depth, l2_ftw_proc_t *proc, void *user
return res;
}
+
+int l2_launcher__parse_u64(const char *num, size_t len, uint64_t *onum)
+{
+ uint64_t accum = 0;
+ for (; len; --len, ++num) {
+ accum *= 10;
+ if (*num >= '0' && *num <= '9') {
+ accum += *num - '0';
+ } else {
+ return -1;
+ }
+ }
+
+ *onum = accum;
+ return 0;
+}
+
+int l2_parse_time(const char *timestr, time_t *ocaltime)
+{
+#define L2_TM_PARSE_FIELD(_tmstr, _len, _tmp, _type, _field) do { \
+ if (l2_launcher__parse_u64(_tmstr, _len, &(_tmp)) < 0) return -1; \
+ _field = (_type)(_tmp); \
+ _tmstr += _len; \
+ } while (0)
+
+#define L2_TM_ENSURE_CHAR(_tmstr, _ch) do { \
+ if (*(_tmstr) != _ch) return -1; \
+ _tmstr += 1; \
+ } while (0)
+
+#define L2_TM_ASSERT_RANGE(_field, _min, _max) do { \
+ L2_DIAG_PUSH L2_DIAG_IGNORED(-Wtype-limits) \
+ if (_field < _min || _field > _max) return -1; \
+ L2_DIAG_POP \
+ } while (0)
+
+ uint64_t temp;
+ struct tm otime;
+ time_t timeres;
+ memset(&otime, 0, sizeof(otime));
+ otime.tm_isdst = -1;
+
+#ifndef NDEBUG
+ const char *origstr = timestr;
+#endif
+
+ /* full-date */
+ /* date-fullyear */
+ L2_TM_PARSE_FIELD(timestr, 4, temp, int, otime.tm_year);
+ L2_TM_ENSURE_CHAR(timestr, '-');
+ otime.tm_year -= 1900;
+
+ /* date-month */
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, otime.tm_mon);
+ L2_TM_ASSERT_RANGE(temp, 1, 12);
+ --otime.tm_mon;
+
+ L2_TM_ENSURE_CHAR(timestr, '-');
+
+ /* date-mday */
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, otime.tm_mday);
+ L2_TM_ASSERT_RANGE(temp, 1, 31);
+
+ if (*timestr != 't' && *timestr != 'T') return -1;
+ ++timestr;
+
+ /* full-time */
+
+ /* partial-time */
+ /* time-hour */
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, otime.tm_hour);
+ L2_TM_ASSERT_RANGE(temp, 0, 23);
+ L2_TM_ENSURE_CHAR(timestr, ':');
+
+ /* time-minute */
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, otime.tm_min);
+ L2_TM_ASSERT_RANGE(temp, 0, 59);
+ L2_TM_ENSURE_CHAR(timestr, ':');
+
+ /* time-second */
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, otime.tm_sec);
+ L2_TM_ASSERT_RANGE(temp, 0, 60); /* for leap seconds */
+
+ /* ignoring time-secfrac (idc about it lol) */
+ if (*timestr == '.') {
+ do {
+ ++timestr;
+ } while (*timestr >= '0' && *timestr <= '9');
+ }
+
+ /* time-offset */
+ if (*timestr == 'Z' || *timestr == 'z') {
+ goto done;
+ }
+
+ int tzoff_mult;
+ switch (*timestr) {
+ case '+':
+ tzoff_mult = 1;
+ break;
+ case '-':
+ tzoff_mult = -1;
+ break;
+ default: return -1;
+ }
+
+ ++timestr;
+
+ CMD_DEBUG("trying to parse timestamp %s, which has zoneoffset. "
+ "This is not fully supported (contains bugs 100%% guaranteed or your money back)", origstr);
+
+ int houroff;
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, houroff);
+ L2_TM_ASSERT_RANGE(houroff, 0, 23);
+ L2_TM_ENSURE_CHAR(timestr, ':');
+
+ int minoff;
+ L2_TM_PARSE_FIELD(timestr, 2, temp, int, minoff);
+ L2_TM_ASSERT_RANGE(minoff, 0, 59);
+
+ otime.tm_hour -= houroff * tzoff_mult;
+ otime.tm_min -= minoff * tzoff_mult;
+
+done:
+ timeres = mktime(&otime);
+ if (timeres == (time_t)-1) return -1;
+ *ocaltime = timeres;
+
+ return 0;
+}