From f080c0e765878ae91949d91a0bc10b87e6c8269b Mon Sep 17 00:00:00 2001
From: Ash Wolf <ninji@wuffs.org>
Date: Wed, 12 Oct 2022 15:05:04 +0100
Subject: finish Posix.c

---
 command_line/CmdLine/Src/OSLib/Posix.c | 111 ++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 7 deletions(-)

(limited to 'command_line/CmdLine/Src/OSLib')

diff --git a/command_line/CmdLine/Src/OSLib/Posix.c b/command_line/CmdLine/Src/OSLib/Posix.c
index 0711559..e836653 100644
--- a/command_line/CmdLine/Src/OSLib/Posix.c
+++ b/command_line/CmdLine/Src/OSLib/Posix.c
@@ -57,6 +57,7 @@ uOSTypePair OS_TEXTTYPE = {0666};
 int OS_Create(const OSSpec *spec, const uOSTypePair *type) {
     int h;
     int err;
+
     CONVERT_SPEC(spec, intbuf);
     h = open(intbuf, O_CREAT | O_TRUNC, type->perm);
     if (h < 0)
@@ -64,7 +65,7 @@ int OS_Create(const OSSpec *spec, const uOSTypePair *type) {
     close(h);
 
     err = OS_SetFileType(spec, type);
-    return (err < 1) ? EPERM : 0;
+    return ((err == 0) || (err == EPERM)) ? 0 : err;
 }
 
 int OS_Status(const OSSpec *spec) {
@@ -86,10 +87,11 @@ int OS_GetFileType(const OSSpec *spec, uOSTypePair *type) {
 }
 
 int OS_SetFileType(const OSSpec *spec, const uOSTypePair *type) {
-    int err, oldmask;
+    int oldmask;
+    int err;
 
     CONVERT_SPEC(spec, intbuf);
-    oldmask = umask(0) & UF_SETTABLE;
+    oldmask = umask(0);
     err = chmod(intbuf, type->perm & ~oldmask);
     umask(oldmask);
 
@@ -353,13 +355,55 @@ char *OS_GetDirPtr(char *path) {
     return path;
 }
 
-static int OS_CompactPath(const char *src, char *dst) {
+static int OS_CompactPath(char *src, char *dst) {
     char buf[256];
     char *bptr;
     char *to;
     char *from;
     char *start;
     char *brk;
+
+    start = OS_GetDirPtr(src);
+    if (dst == NULL)
+        bptr = buf;
+    else
+        bptr = dst;
+
+    strncpy(bptr, src, start - src);
+    bptr = bptr + (start - src);
+    from = start;
+    to = bptr;
+    while (*from) {
+        brk = from + 1;
+        while (*brk && *brk != '/')
+            ++brk;
+
+        if ((brk - from) == 1) {
+            from = brk;
+        } else if ((brk - from) == 2 && from[1] == '.') {
+            from = brk;
+        } else if ((brk - from) == 3 && from[1] == '.' && from[2] == '.') {
+            if (to > bptr) {
+                do {
+                    to--;
+                } while (to >= bptr && *to != '/');
+            }
+            from = brk;
+        } else {
+            while (from < brk) {
+                *(to++) = *(from++);
+            }
+        }
+    }
+
+    if (to == bptr || from[-1] == '/')
+        *(to++) = '/';
+    *to = 0;
+
+    if (!dst)
+        strcpy(src, buf);
+
+    return 0;
 }
 
 int OS_EqualPath(const char *a, const char *b) {
@@ -823,17 +867,70 @@ void OS_TimeToMac(time_t sectm, UInt32 *secs) {
     int ydays;
 
     tmrec = localtime(&sectm);
-    // this is horrendous lol
+    years = tmrec->tm_year - 4;
+
+    ydays =
+            (years * 365) +
+            ((years + 3) / 4) -
+            ((years + 4) / 100) +
+            ((years - 296) / 400);
+
+    *secs =
+            ((ydays + tmrec->tm_yday) * 86400)
+            + (tmrec->tm_hour * 3600)
+            + (tmrec->tm_min * 60)
+            + (tmrec->tm_sec)
+            + (tmrec->tm_isdst ? -3600 : 0);
 }
 
 void OS_MacToTime(UInt32 secs, time_t *sectm) {
+    static int monthdays[12] = {
+            31, 28, 31, 30,
+            31, 30, 31, 31,
+            30, 31, 30, 31
+    };
     struct tm tmrec;
     int month;
+
+    memset(&tmrec, 0, sizeof(tmrec));
+    tmrec.tm_sec = secs % 60; // line 1523
+    tmrec.tm_min = (secs / 60) % 60; // line 1524
+    tmrec.tm_hour = (secs / 3600) % 24; // line 1525
+    tmrec.tm_yday = (secs / 86400) % 365;
+    tmrec.tm_year = (secs / 31536000) + 4; // line 1533
+    tmrec.tm_yday -=
+            ((((secs / 31536000) + 3) / 4)
+            -
+            (((secs / 31536000) + 4) / 100)
+            +
+            ((SInt32)((secs / 31536000) - 296) / 400))
+            ;
+
+    if ((tmrec.tm_year % 4) && ((tmrec.tm_year % 100) || !(tmrec.tm_year % 400))) {
+        monthdays[1] = 28;
+    } else {
+        monthdays[1] = 29;
+    }
+
+    if (tmrec.tm_yday >= (monthdays[1] + 62) && tmrec.tm_yday < (monthdays[1] + 245)) {
+        tmrec.tm_hour++;
+        if (tmrec.tm_hour >= 24) {
+            tmrec.tm_yday++;
+            tmrec.tm_hour -= 24;
+        }
+    }
+
+    for (month = 0; tmrec.tm_yday >= monthdays[month]; month++) {
+        tmrec.tm_yday -= monthdays[month];
+    }
+    tmrec.tm_mon = month;
+    tmrec.tm_mday = tmrec.tm_yday + 1;
+
+    *sectm = mktime(&tmrec);
 }
 
 SInt16 OS_RefToMac(int ref) {
-    //return (ref >= -1) ? (ref + 1) : ref;
-    // wtf is going on here augh
+    return (ref < -1) ? (SInt16) 0 : (SInt16) (ref + 1);
 }
 
 int OS_MacToRef(SInt16 refnum) {
-- 
cgit v1.2.3