summaryrefslogtreecommitdiff
path: root/command_line
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2022-10-12 03:03:57 +0100
committerAsh Wolf <ninji@wuffs.org>2022-10-12 03:03:57 +0100
commit45e57168fa0d33206731e391fb24759ddf179861 (patch)
treed09621ca6e201865ce9975fa72426f63ac054fd3 /command_line
parent4c9d73d7243c82ca3f55d2d8a388328968303b3f (diff)
downloadMWCC-45e57168fa0d33206731e391fb24759ddf179861.tar.gz
MWCC-45e57168fa0d33206731e391fb24759ddf179861.zip
lots more reorganisation, done part of OSLib
Diffstat (limited to 'command_line')
-rw-r--r--command_line/CmdLine/Src/OSLib/FileHandles.c29
-rw-r--r--command_line/CmdLine/Src/OSLib/Generic.c93
-rw-r--r--command_line/CmdLine/Src/OSLib/MacFileTypes.c29
-rw-r--r--command_line/CmdLine/Src/OSLib/MacSpecs.c25
-rw-r--r--command_line/CmdLine/Src/OSLib/MemUtils.c21
-rw-r--r--command_line/CmdLine/Src/OSLib/Posix.c866
-rw-r--r--command_line/CmdLine/Src/OSLib/StringExtras.c17
-rw-r--r--command_line/CmdLine/Src/OSLib/StringUtils.c49
8 files changed, 1129 insertions, 0 deletions
diff --git a/command_line/CmdLine/Src/OSLib/FileHandles.c b/command_line/CmdLine/Src/OSLib/FileHandles.c
index e69de29..4609d77 100644
--- a/command_line/CmdLine/Src/OSLib/FileHandles.c
+++ b/command_line/CmdLine/Src/OSLib/FileHandles.c
@@ -0,0 +1,29 @@
+#include "oslib.h"
+
+static int OS_LoadFileHandle(OSFileHandle *hand) {
+
+}
+
+static int OS_WriteFileHandle(OSFileHandle *hand) {
+
+}
+
+int OS_NewFileHandle(const OSSpec *spec, OSHandle *src, Boolean writeable, OSFileHandle *hand) {
+
+}
+
+int OS_LockFileHandle(OSFileHandle *hand, Ptr *ptr, UInt32 *size) {
+
+}
+
+int OS_UnlockFileHandle(OSFileHandle *hand) {
+
+}
+
+int OS_FreeFileHandle(OSFileHandle *hand) {
+
+}
+
+void OS_GetFileHandleSpec(const OSFileHandle *hand, OSSpec *spec) {
+
+}
diff --git a/command_line/CmdLine/Src/OSLib/Generic.c b/command_line/CmdLine/Src/OSLib/Generic.c
index e69de29..4430790 100644
--- a/command_line/CmdLine/Src/OSLib/Generic.c
+++ b/command_line/CmdLine/Src/OSLib/Generic.c
@@ -0,0 +1,93 @@
+#include "oslib.h"
+
+static char wildname[63];
+static char wilddir[255];
+static OSOpenedDir wilddirref;
+static OSSpec wildmatch;
+char STSbuf[256];
+
+int WildCardMatch(const char *wild, const char *name) {
+ char next;
+ const char *prev;
+}
+
+OSSpec *OS_MatchPath(const char *path) {
+ char filename[64];
+ Boolean isfile;
+ OSSpec spec;
+ const char *nptr;
+}
+
+char *OS_GetFileNamePtr(char *path) {
+ char *ptr;
+}
+
+char *OS_GetDirName(const OSPathSpec *spec, char *buf, int size) {
+ char *path;
+ char *pptr;
+}
+
+int OS_MakeSpec2(const char *path, const char *filename, OSSpec *spec) {
+ char bpath[256];
+ char *eptr;
+ int pthlen;
+ int fnlen;
+}
+
+int OS_MakeSpecWithPath(OSPathSpec *path, const char *filename, Boolean noRelative, OSSpec *spec) {
+ Boolean relpath;
+ char buf[256];
+ char *mptr;
+ char *eptr;
+}
+
+int OS_NameSpecChangeExtension(OSNameSpec *spec, const char *ext, Boolean append) {
+ char tmp[64];
+ char *per;
+}
+
+int OS_NameSpecSetExtension(OSNameSpec *spec, const char *ext) {
+ char tmp[64];
+ char *per;
+}
+
+char *OS_CompactPaths(char *buf, const char *p, const char *n, int size) {
+ int plen;
+ int nlen;
+ char *ptr;
+ int bidx;
+}
+
+char *OS_SpecToStringRelative(const OSSpec *spec, const OSPathSpec *cwdspec, char *path, int size) {
+ char fullbuf[256];
+ char *full;
+ char cwfbuf[256];
+ char *cwd;
+ OSPathSpec mycwdspec;
+ char *pptr;
+}
+
+int OS_FindFileInPath(const char *filename, const char *plist, OSSpec *spec) {
+ char *next;
+ char path[256];
+ int err;
+}
+
+int OS_FindProgram(const char *filename, OSSpec *spec) {
+ char *plist;
+ int err;
+ char temp[256];
+}
+
+int OS_CopyHandle(OSHandle *hand, OSHandle *copy) {
+ int err;
+ UInt32 sz;
+ void *f;
+ void *t;
+}
+
+int OS_AppendHandle(OSHandle *hand, const void *data, UInt32 len) {
+ int err;
+ UInt32 sz;
+ void *buffer;
+}
diff --git a/command_line/CmdLine/Src/OSLib/MacFileTypes.c b/command_line/CmdLine/Src/OSLib/MacFileTypes.c
index e69de29..9d18723 100644
--- a/command_line/CmdLine/Src/OSLib/MacFileTypes.c
+++ b/command_line/CmdLine/Src/OSLib/MacFileTypes.c
@@ -0,0 +1,29 @@
+#include "oslib.h"
+
+void OS_AddFileTypeMappingList(OSFileTypeMappings **list, OSFileTypeMappingList *entry) {
+
+}
+
+void OS_UseFileTypeMappings(OSFileTypeMappings *list) {
+
+}
+
+void OS_MacType_To_OSType(OSType mactype, uOSTypePair *type) {
+
+}
+
+int OS_SetMacFileType(const OSSpec *spec, OSType mactype) {
+
+}
+
+Boolean OS_GetMacFileTypeMagic(const char *buffer, int count, OSType *mactype) {
+
+}
+
+int OS_GetMacFileType(const OSSpec *spec, OSType *mactype) {
+
+}
+
+int OS_SetMacFileCreatorAndType(const OSSpec *spec, OSType creator, OSType mactype) {
+
+}
diff --git a/command_line/CmdLine/Src/OSLib/MacSpecs.c b/command_line/CmdLine/Src/OSLib/MacSpecs.c
index e69de29..8648324 100644
--- a/command_line/CmdLine/Src/OSLib/MacSpecs.c
+++ b/command_line/CmdLine/Src/OSLib/MacSpecs.c
@@ -0,0 +1,25 @@
+#include "oslib.h"
+
+int OS_OSPathSpec_To_VolDir(const OSPathSpec *spec, SInt16 *vRefNum, SInt32 *dirID) {
+
+}
+
+int OS_OSSpec_To_FSSpec(const OSSpec *spec, FSSpec *fss) {
+
+}
+
+int OS_VolDir_To_OSNameSpec(SInt16 vRefNum, SInt32 dirID, OSNameSpec *spec, SInt32 *parID) {
+
+}
+
+int OS_VolDir_To_OSPathSpec(SInt16 vRefNum, SInt32 dirID, OSPathSpec *spec) {
+
+}
+
+int OS_FSSpec_To_OSSpec(const FSSpec *fss, OSSpec *spec) {
+
+}
+
+int OS_GetRsrcOSSpec(const OSSpec *spec, OSSpec *rspec, Boolean create) {
+
+}
diff --git a/command_line/CmdLine/Src/OSLib/MemUtils.c b/command_line/CmdLine/Src/OSLib/MemUtils.c
index e69de29..4eb611c 100644
--- a/command_line/CmdLine/Src/OSLib/MemUtils.c
+++ b/command_line/CmdLine/Src/OSLib/MemUtils.c
@@ -0,0 +1,21 @@
+#include "oslib.h"
+
+void *xmalloc(const char *what, int size) {
+
+}
+
+void *xcalloc(const char *what, int size) {
+
+}
+
+void *xrealloc(const char *what, void *old, int size) {
+
+}
+
+char *xstrdup(const char *str) {
+
+}
+
+void xfree(void *ptr) {
+
+}
diff --git a/command_line/CmdLine/Src/OSLib/Posix.c b/command_line/CmdLine/Src/OSLib/Posix.c
index e69de29..0711559 100644
--- a/command_line/CmdLine/Src/OSLib/Posix.c
+++ b/command_line/CmdLine/Src/OSLib/Posix.c
@@ -0,0 +1,866 @@
+#include "oslib.h"
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <time.h>
+#include <utime.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+enum {
+ OSErrNeg2 = -2
+};
+
+static char *lastdlerr;
+static char intbuf[256];
+enum { MAX_PATH = 256 };
+
+#define CONVERT_SPEC(spec, pathbuf) \
+do { \
+int _plen = strlen((spec)->path.s); \
+int _nlen = strlen((spec)->name.s); \
+if (_plen + _nlen >= sizeof(pathbuf)) return 63; \
+memcpy((pathbuf), (spec)->path.s, _plen); \
+memcpy((pathbuf) + _plen, (spec)->name.s, _nlen + 1); \
+} while (0)
+
+#define CONVERT_PATHSPEC(spec, pathbuf) \
+do { \
+int _plen = strlen((spec)->s); \
+if (_plen >= sizeof(pathbuf)) return 63;\
+memcpy((pathbuf), (spec)->s, _plen + 1);\
+if (_plen > 1) { \
+if ((pathbuf)[_plen - 1] == '/') \
+(pathbuf)[_plen - 1] = 0; \
+} \
+} while (0)
+
+const char *OS_GetErrText(int err) {
+ if (err == -2) {
+ return !lastdlerr ? "Shared library function failed" : lastdlerr;
+ } else {
+ return strerror(err);
+ }
+}
+
+int OS_InitProgram(int *pArgc, const char ***pArgv) {
+ return 0;
+}
+
+int OS_TermProgram() {
+ return 0;
+}
+
+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)
+ return errno;
+ close(h);
+
+ err = OS_SetFileType(spec, type);
+ return (err < 1) ? EPERM : 0;
+}
+
+int OS_Status(const OSSpec *spec) {
+ struct stat st;
+ CONVERT_SPEC(spec, intbuf);
+ if (stat(intbuf, &st))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_GetFileType(const OSSpec *spec, uOSTypePair *type) {
+ struct stat st;
+ CONVERT_SPEC(spec, intbuf);
+ if (stat(intbuf, &st) < 0)
+ return errno;
+ type->perm = st.st_mode;
+ return 0;
+}
+
+int OS_SetFileType(const OSSpec *spec, const uOSTypePair *type) {
+ int err, oldmask;
+
+ CONVERT_SPEC(spec, intbuf);
+ oldmask = umask(0) & UF_SETTABLE;
+ err = chmod(intbuf, type->perm & ~oldmask);
+ umask(oldmask);
+
+ if (err < 0)
+ return errno;
+ return 0;
+}
+
+int OS_GetFileTime(const OSSpec *spec, time_t *crtm, time_t *chtm) {
+ struct stat st;
+ CONVERT_SPEC(spec, intbuf);
+ if (stat(intbuf, &st) < 0)
+ return errno;
+ if (crtm)
+ *crtm = st.st_ctimespec.tv_sec;
+ if (chtm)
+ *chtm = st.st_mtimespec.tv_sec;
+ return 0;
+}
+
+int OS_SetFileTime(const OSSpec *spec, const time_t *crtm, const time_t *chtm) {
+ struct utimbuf buf;
+ struct stat st;
+ CONVERT_SPEC(spec, intbuf);
+ if (stat(intbuf, &st) < 0)
+ return errno;
+ buf.actime = chtm ? *chtm : st.st_atimespec.tv_sec;
+ buf.modtime = crtm ? *crtm : st.st_mtimespec.tv_sec;
+ if (utime(intbuf, &buf) < 0)
+ return errno;
+ return 0;
+}
+
+int OS_Open(const OSSpec *spec, OSOpenMode mode, int *ref) {
+ static int modetrans[4] = {
+ O_RDONLY,
+ O_WRONLY,
+ O_RDWR,
+ O_RDONLY | O_APPEND
+ };
+ CONVERT_SPEC(spec, intbuf);
+ *ref = open(intbuf, modetrans[mode]);
+ if (*ref < 0) {
+ *ref = -1;
+ return errno;
+ }
+ return 0;
+}
+
+int OS_Write(int ref, const void *buffer, UInt32 *length) {
+ struct stat st;
+ UInt32 pos;
+
+ if (fstat(ref, &st) < 0)
+ return errno;
+
+ pos = lseek(ref, 0, SEEK_CUR);
+ if (pos > st.st_size && !*length) {
+ lseek(ref, -1, SEEK_CUR);
+ if (write(ref, "", 1) != 1) {
+ *length = 0;
+ return errno;
+ }
+ }
+
+ *length = write(ref, buffer, *length);
+ if (((SInt32) *length) < 0)
+ return errno;
+ return 0;
+}
+
+int OS_Read(int ref, void *buffer, UInt32 *length) {
+ *length = read(ref, buffer, *length);
+ if (((SInt32) *length) < 0)
+ return errno;
+ return 0;
+}
+
+int OS_Seek(int ref, OSSeekMode how, SInt32 offset) {
+ static int howtrans[3] = {
+ SEEK_CUR,
+ SEEK_SET,
+ SEEK_END
+ };
+
+ return (lseek(ref, offset, howtrans[how]) < 0) ? errno : 0;
+}
+
+int OS_Tell(int ref, SInt32 *offset) {
+ *offset = lseek(ref, 0, SEEK_CUR);
+ if (*offset < 0)
+ return errno;
+ else
+ return 0;
+}
+
+int OS_Close(int ref) {
+ if (ref == -1)
+ return EBADF;
+
+ if (close(ref))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_GetSize(int ref, UInt32 *length) {
+ struct stat st;
+ if (fstat(ref, &st) < 0) {
+ return errno;
+ } else {
+ *length = st.st_size;
+ return 0;
+ }
+}
+
+int OS_SetSize(int ref, UInt32 size) {
+ if (ftruncate(ref, size))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_Delete(const OSSpec *spec) {
+ CONVERT_SPEC(spec, intbuf);
+ if (unlink(intbuf))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_Rename(const OSSpec *oldspec, const OSSpec *newspec) {
+ char newbuf[256];
+ CONVERT_SPEC(newspec, newbuf);
+ CONVERT_SPEC(oldspec, intbuf);
+ return rename(intbuf, newbuf) ? errno : 0;
+}
+
+int OS_Mkdir(const OSSpec *spec) {
+ CONVERT_SPEC(spec, intbuf);
+ if (mkdir(intbuf, 0777))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_Rmdir(const OSPathSpec *spec) {
+ CONVERT_PATHSPEC(spec, intbuf);
+ if (rmdir(intbuf))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_Chdir(const OSPathSpec *spec) {
+ CONVERT_PATHSPEC(spec, intbuf);
+ if (chdir(intbuf))
+ return errno;
+ else
+ return 0;
+}
+
+int OS_GetCWD(OSPathSpec *spec) {
+ char *ptr;
+ if (!getcwd(spec->s, sizeof(spec->s)))
+ return errno;
+
+ ptr = &spec->s[strlen(spec->s)];
+ if (ptr[-1] != '/')
+ strcpy(ptr, "/");
+ return 0;
+}
+
+extern char **environ;
+int OS_Execute(OSSpec *spec, char **argv, char **envp, const char *stdoutfile, const char *stderrfile, int *exitcode) {
+ int svstdout;
+ int svstderr;
+ pid_t kidpid;
+ int status;
+ int err; // not in stabs but i think this exists...?
+
+ if (stdoutfile) {
+ svstdout = dup(1);
+ close(1);
+ if (open(stdoutfile, O_CREAT|O_TRUNC|O_WRONLY, 0666) < 0) {
+ status = errno;
+ dup2(svstdout, 1);
+ close(svstdout);
+ return status;
+ }
+ }
+
+ if (stderrfile) {
+ svstderr = dup(2);
+ close(2);
+ if (open(stderrfile, O_CREAT|O_TRUNC|O_WRONLY, 0666) < 0) {
+ status = errno;
+ dup2(svstderr, 2);
+ close(svstderr);
+ return status;
+ }
+ }
+
+ kidpid = fork();
+ if (!kidpid) {
+ if (execve(argv[0], argv, (envp && envp[0]) ? envp : environ) < 0)
+ exit(-1);
+ return EINVAL;
+ } else {
+ if (stdoutfile) {
+ dup2(svstdout, 1);
+ close(svstdout);
+ }
+ if (stderrfile) {
+ dup2(svstderr, 2);
+ close(svstderr);
+ }
+ *exitcode = 0;
+
+ err = (waitpid(kidpid, &status, 0) <= 0) ? errno : 0;
+
+ if (!(status & 0x7F))
+ *exitcode = status >> 8;
+
+ if ((status & 0x7F) != 0x7F && (status & 0x7F) != 0)
+ *exitcode = -(status & 0x7F);
+
+ return err;
+ }
+}
+
+int OS_IsLegalPath(const char *path) {
+ const char *scan = path;
+ int pthlen;
+ int fnlen;
+
+ pthlen = 0;
+ fnlen = 0;
+
+ while (*scan) {
+ if (*scan == '/')
+ fnlen = 0;
+ else
+ fnlen++;
+ ++pthlen;
+ if (fnlen > 63 || pthlen > 255)
+ return ENAMETOOLONG;
+ //if ((fnlen = (*scan == '/') ? 0 : (fnlen + 1)) > 63 || ++pthlen > 255)
+ // return ENAMETOOLONG;
+ ++scan;
+ }
+
+ return 0;
+}
+
+int OS_IsFullPath(const char *path) {
+ return path[0] == '/';
+}
+
+char *OS_GetDirPtr(char *path) {
+ return path;
+}
+
+static int OS_CompactPath(const char *src, char *dst) {
+ char buf[256];
+ char *bptr;
+ char *to;
+ char *from;
+ char *start;
+ char *brk;
+}
+
+int OS_EqualPath(const char *a, const char *b) {
+ return !strcmp(a, b);
+}
+
+int OS_CanonPath(char *src, char *dst) {
+ int idx;
+
+ if (strlen(src) > 255)
+ return ENAMETOOLONG;
+
+ if (!dst)
+ dst = src;
+
+ for (idx = 0; src[idx]; idx++) {
+ if (src[idx] == '\\')
+ dst[idx] = '/';
+ else
+ dst[idx] = src[idx];
+ }
+
+ dst[idx] = 0;
+ return 0;
+}
+
+int OS_MakeSpec(const char *path, OSSpec *spec, Boolean *isfile) {
+ char tmp[256];
+ struct stat st;
+ char *ptr;
+ int len;
+ int err;
+ char *end;
+ char orig[256];
+
+ spec->name.s[0] = 0;
+ spec->path.s[0] = 0;
+ err = OS_CanonPath((char *) path, tmp);
+ if (err)
+ return err;
+
+ if (!OS_IsFullPath(tmp)) {
+ strcpy(orig, tmp);
+ if (!getcwd(tmp, sizeof(tmp)))
+ return errno;
+
+ ptr = tmp + strlen(tmp) - 1;
+ if (ptr[0] != '/') {
+ ptr[1] = '/';
+ ptr[2] = 0;
+ ptr += 2;
+ }
+
+ if (((ptr - tmp) + strlen(orig)) >= 256)
+ return ENAMETOOLONG;
+
+ strcpy(ptr, orig);
+ } else {
+ if (strlen(tmp) >= 256)
+ return ENAMETOOLONG;
+ }
+
+ err = OS_CompactPath(tmp, 0);
+ if (err)
+ return err;
+ err = OS_IsLegalPath(tmp);
+ if (err)
+ return err;
+
+ if (!stat(tmp, &st)) {
+ ptr = tmp + strlen(tmp);
+ if (ptr[-1] == '/')
+ ptr--;
+ if ((st.st_mode & S_IFMT) == S_IFDIR) {
+ if (isfile)
+ *isfile = 0;
+ ptr[0] = '/';
+ ptr++;
+ } else {
+ if (isfile)
+ *isfile = 1;
+ }
+ *ptr = 0;
+ } else {
+ if (errno != ENOENT)
+ return errno;
+ if (isfile)
+ *isfile = 1;
+ }
+
+ ptr = strrchr(tmp, '/') + 1;
+ len = ptr - tmp;
+ if (len >= 256) {
+ spec->path.s[0] = 0;
+ return ENAMETOOLONG;
+ }
+
+ memcpy(spec->path.s, tmp, len);
+ spec->path.s[len] = 0;
+
+ len = strlen(ptr);
+ if (len >= 64) {
+ spec->name.s[0] = 0;
+ return ENAMETOOLONG;
+ }
+
+ memcpy(spec->name.s, ptr, len);
+ spec->name.s[len] = 0;
+
+ return 0;
+}
+
+int OS_MakeFileSpec(const char *path, OSSpec *spec) {
+ Boolean isfile;
+ int err;
+
+ err = OS_MakeSpec(path, spec, &isfile);
+ if (err)
+ return err;
+ else
+ return (isfile != 0) ? 0 : EISDIR;
+}
+
+int OS_MakePathSpec(const char *vol, const char *dir, OSPathSpec *spec) {
+ Boolean isfile;
+ OSSpec tmp;
+ int err;
+ char path[256];
+
+ if (((vol ? strlen(vol) : 0) + (dir ? strlen(dir) : 0) + 2) > 256)
+ return ENAMETOOLONG;
+
+ sprintf(path,
+ "%s%s%s",
+ vol ? (strchr("/\\:", vol[0]) ? "" : "/") : "",
+ vol ? vol : "",
+ dir ? dir : ""
+ );
+
+ err = OS_MakeSpec(path, &tmp, &isfile);
+ strcpy(spec->s, tmp.path.s);
+ if (err)
+ return err;
+
+ if (isfile)
+ return !OS_Status(&tmp) ? ENOTDIR : ENOENT;
+
+ return 0;
+}
+
+int OS_MakeNameSpec(const char *name, OSNameSpec *spec) {
+ int len;
+
+ len = strlen(name);
+ spec->s[0] = 0;
+ if (len > 63)
+ return ENAMETOOLONG;
+ if (strchr(name, '/'))
+ return EISDIR;
+ if (strlen(name) > 63)
+ return ENAMETOOLONG;
+ memcpy(spec->s, name, len + 1);
+ return 0;
+}
+
+int OS_GetRootSpec(OSPathSpec *spec) {
+ strcpy(spec->s, "/");
+ return 0;
+}
+
+char *OS_SpecToString(const OSSpec *spec, char *path, int size) {
+ int plen;
+ int nlen;
+
+ if (!size)
+ size = 256;
+
+ if (!path) {
+ path = malloc(size);
+ if (!path)
+ return 0;
+ }
+
+ plen = strlen(spec->path.s);
+ nlen = strlen(spec->name.s);
+ if ((plen + nlen) >= size) {
+ if (plen >= size) {
+ nlen = 0;
+ plen = size - 1;
+ } else {
+ nlen = (size - plen) - 1;
+ }
+ }
+
+ memcpy(path, spec->path.s, plen);
+ memcpy(&path[plen], spec->name.s, nlen);
+ path[plen + nlen] = 0;
+ return path;
+}
+
+char *OS_PathSpecToString(const OSPathSpec *pspec, char *path, int size) {
+ int plen;
+
+ if (!size)
+ size = 256;
+
+ if (!path) {
+ path = malloc(size);
+ if (!path)
+ return 0;
+ }
+
+ plen = strlen(pspec->s);
+ if (plen >= size)
+ plen = size - 1;
+
+ memcpy(path, pspec->s, plen);
+ path[plen] = 0;
+ return path;
+}
+
+char *OS_NameSpecToString(const OSNameSpec *nspec, char *name, int size) {
+ int nlen;
+
+ if (!size)
+ size = 64;
+
+ if (!name) {
+ name = malloc(size);
+ if (!name)
+ return 0;
+ }
+
+ nlen = strlen(nspec->s);
+ if (nlen >= size)
+ nlen = size - 1;
+
+ memcpy(name, nspec->s, nlen);
+ name[nlen] = 0;
+ return name;
+}
+
+int OS_SizeOfPathSpec(const OSPathSpec *spec) {
+ return strlen(spec->s) + 1;
+}
+
+int OS_SizeOfNameSpec(const OSNameSpec *spec) {
+ return strlen(spec->s) + 1;
+}
+
+int OS_EqualSpec(const OSSpec *a, const OSSpec *b) {
+ return OS_EqualPathSpec(&a->path, &b->path) && OS_EqualNameSpec(&a->name, &b->name);
+}
+
+int OS_EqualPathSpec(const OSPathSpec *a, const OSPathSpec *b) {
+ return !strcmp(a->s, b->s);
+}
+
+int OS_EqualNameSpec(const OSNameSpec *a, const OSNameSpec *b) {
+ return !strcmp(a->s, b->s);
+}
+
+int OS_IsDir(const OSSpec *spec) {
+ struct stat st;
+
+ if (!OS_SpecToString(spec, intbuf, sizeof(intbuf)))
+ return 0;
+ if (stat(intbuf, &st) < 0)
+ return 0;
+ return ((st.st_mode & S_IFMT) == S_IFDIR);
+}
+
+int OS_IsFile(const OSSpec *spec) {
+ struct stat st;
+
+ if (!OS_SpecToString(spec, intbuf, sizeof(intbuf)))
+ return 0;
+ if (stat(intbuf, &st) < 0)
+ return 0;
+ return ((st.st_mode & S_IFMT) != S_IFDIR);
+}
+
+int OS_IsLink(const OSSpec *spec) {
+ struct stat st;
+ char *ptr;
+
+ if (!OS_SpecToString(spec, intbuf, sizeof(intbuf)))
+ return 0;
+
+ ptr = intbuf + strlen(intbuf) - 1;
+ if (*ptr == '/')
+ *ptr = 0;
+
+ if (lstat(intbuf, &st) < 0)
+ return 0;
+
+ return ((st.st_mode & S_IFMT) == S_IFLNK);
+}
+
+int OS_ResolveLink(const OSSpec *link, OSSpec *target) {
+ char fn[64];
+ char path[256];
+ int len;
+
+ if (!OS_SpecToString(link, intbuf, sizeof(intbuf)))
+ return ENAMETOOLONG;
+
+ len = readlink(intbuf, fn, sizeof(fn));
+ if (len < 0)
+ return errno;
+ fn[len] = 0;
+
+ sprintf(path, "%s%s", (fn[0] != '/') ? link->path.s : "", fn);
+ return OS_MakeSpec(path, target, 0);
+}
+
+int OS_OpenDir(const OSPathSpec *spec, OSOpenedDir *ref) {
+ DIR *dptr;
+
+ CONVERT_PATHSPEC(spec, intbuf);
+ dptr = opendir(intbuf);
+ if (!dptr) {
+ ref->dir = 0;
+ return errno;
+ }
+
+ ref->spec = *spec;
+ ref->dir = dptr;
+ return 0;
+}
+
+int OS_ReadDir(OSOpenedDir *ref, OSSpec *spec, char *filename, Boolean *isfile) {
+ struct dirent *de;
+ char fn[256];
+ int err;
+ int len;
+
+ do {
+ de = readdir(ref->dir);
+ if (!de)
+ return ENOENT;
+ } while (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") || (strlen(ref->spec.s) + strlen(de->d_name) >= 256));
+
+ len = strlen(ref->spec.s);
+ strncpy(fn, ref->spec.s, 255);
+ if (len < 256) {
+ strncpy(&fn[len], de->d_name, 255 - len);
+ fn[255] = 0;
+ } else {
+ return ENAMETOOLONG;
+ }
+
+ strncpy(filename, de->d_name, 63);
+ filename[63] = 0;
+
+ return OS_MakeSpec(fn, spec, isfile);
+}
+
+int OS_CloseDir(OSOpenedDir *ref) {
+ if (ref->dir)
+ return closedir(ref->dir);
+ else
+ return 0;
+}
+
+UInt32 OS_GetMilliseconds() {
+ struct tms tms;
+ return times(&tms) * 1000 / CLOCKS_PER_SEC;
+}
+
+void OS_GetTime(time_t *p) {
+ time(p);
+}
+
+int OS_NewHandle(UInt32 size, OSHandle *hand) {
+ hand->addr = 0;
+ hand->used = size;
+ hand->size = (size + 256) & ~255;
+ hand->addr = malloc(hand->size);
+ return !hand->addr ? ENOMEM : 0;
+}
+
+int OS_ResizeHandle(OSHandle *hand, UInt32 size) {
+ UInt32 nsize;
+ void *naddr;
+
+ nsize = (size + 256) & ~255;
+ naddr = realloc(hand->addr, nsize);
+ if (!naddr)
+ return ENOMEM;
+
+ hand->addr = naddr;
+ hand->size = nsize;
+ hand->used = size;
+ return 0;
+}
+
+void *OS_LockHandle(OSHandle *hand) {
+ return hand->addr;
+}
+
+void OS_UnlockHandle(OSHandle *hand) {
+}
+
+int OS_FreeHandle(OSHandle *hand) {
+ if (!hand->addr)
+ return ENOMEM;
+
+ free(hand->addr);
+ hand->size = 0;
+ hand->used = 0;
+ hand->addr = 0;
+ return 0;
+}
+
+int OS_GetHandleSize(OSHandle *hand, UInt32 *size) {
+ if (hand->addr) {
+ *size = hand->used;
+ return 0;
+ } else {
+ *size = 0;
+ return ENOMEM;
+ }
+}
+
+void OS_InvalidateHandle(OSHandle *hand) {
+ hand->addr = 0;
+ hand->used = 0;
+}
+
+Boolean OS_ValidHandle(OSHandle *hand) {
+ return (hand && hand->addr);
+}
+
+OSErr OS_MacError(int err) {
+ switch (err) {
+ case 0: return noErr;
+ case ENOENT /*2*/: return fnfErr;
+ case EFAULT /*14*/:
+ case EINVAL /*22*/: return paramErr;
+ case ENOTDIR /*20*/: return dirNFErr;
+ case EISDIR /*21*/: return notAFileErr;
+ case ENAMETOOLONG /*63*/: return bdNamErr;
+ case EBUSY /*16*/: return memLockedErr;
+ case E2BIG /*7*/:
+ case ENOMEM /*12*/: return memFullErr;
+ case EACCES /*13*/: return permErr;
+ case EIO /*5*/: return ioErr;
+ case EEXIST /*17*/: return dupFNErr;
+ case EMFILE /*24*/: return tmfoErr;
+ case EFBIG /*27*/: return fsDataTooBigErr;
+ case EBADF /*9*/: return rfNumErr;
+ case EINTR /*4*/: return abortErr;
+ default: return (OSErr) (0xFFFF8000 | err);
+ }
+}
+
+void OS_TimeToMac(time_t sectm, UInt32 *secs) {
+ struct tm *tmrec;
+ int years;
+ int ydays;
+
+ tmrec = localtime(&sectm);
+ // this is horrendous lol
+}
+
+void OS_MacToTime(UInt32 secs, time_t *sectm) {
+ struct tm tmrec;
+ int month;
+}
+
+SInt16 OS_RefToMac(int ref) {
+ //return (ref >= -1) ? (ref + 1) : ref;
+ // wtf is going on here augh
+}
+
+int OS_MacToRef(SInt16 refnum) {
+ return (refnum >= 0) ? (refnum - 1) : -1;
+}
+
+int OS_OpenLibrary(const char *a, void **lib) {
+ *lib = 0;
+ lastdlerr = "No support for shared libraries";
+ return OSErrNeg2;
+}
+
+int OS_GetLibrarySymbol(void *a, void *b, void **sym) {
+ *sym = 0;
+ lastdlerr = "No support for shared libraries";
+ return OSErrNeg2;
+}
+
+int OS_CloseLibrary(void *a) {
+ lastdlerr = "No support for shared libraries";
+ return OSErrNeg2;
+}
+
+int OS_LoadMacResourceFork(const OSSpec *spec, void **file_data, SInt32 *file_len) {
+ return ENOENT;
+}
+
+int OS_IsMultiByte(const char *str, int offset) {
+ return 0;
+}
diff --git a/command_line/CmdLine/Src/OSLib/StringExtras.c b/command_line/CmdLine/Src/OSLib/StringExtras.c
index e69de29..04ef6b4 100644
--- a/command_line/CmdLine/Src/OSLib/StringExtras.c
+++ b/command_line/CmdLine/Src/OSLib/StringExtras.c
@@ -0,0 +1,17 @@
+#include "oslib.h"
+
+char *strcatn(char *d, const char *s, SInt32 max) {
+
+}
+
+char *strcpyn(char *d, const char *s, SInt32 len, SInt32 max) {
+
+}
+
+int ustrcmp(const char *src, const char *dst) {
+
+}
+
+int ustrncmp(const char *src, const char *dst, UInt32 len) {
+
+}
diff --git a/command_line/CmdLine/Src/OSLib/StringUtils.c b/command_line/CmdLine/Src/OSLib/StringUtils.c
index e69de29..5f0d5bd 100644
--- a/command_line/CmdLine/Src/OSLib/StringUtils.c
+++ b/command_line/CmdLine/Src/OSLib/StringUtils.c
@@ -0,0 +1,49 @@
+#include "oslib.h"
+
+StringPtr _pstrcpy(StringPtr dst, ConstStringPtr src) {
+
+}
+
+void _pstrcat(StringPtr dst, ConstStringPtr src) {
+
+}
+
+void _pstrcharcat(StringPtr to, char ch) {
+
+}
+
+void pstrncpy(StringPtr to, ConstStringPtr from, int max) {
+
+}
+
+void pstrncat(StringPtr to, ConstStringPtr append, int max) {
+
+}
+
+int pstrcmp(ConstStringPtr a, ConstStringPtr b) {
+
+}
+
+int pstrchr(ConstStringPtr str, char find) {
+
+}
+
+void c2pstrcpy(StringPtr dst, const char *src) {
+
+}
+
+void p2cstrcpy(char *dst, ConstStringPtr src) {
+
+}
+
+char *mvprintf(char *mybuf, unsigned int len, const char *format, va_list va) {
+
+}
+
+char *mprintf(char *mybuf, unsigned int len, const char *format, ...) {
+
+}
+
+int HPrintF(Handle text, const char *format, ...) {
+
+}