From: Robert Pengelly Date: Sun, 1 Mar 2026 15:39:05 +0000 (+0000) Subject: Working DOS version X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=b07401e6bd28df133ca62535e1fec3d1052cea50;p=tar.git Working DOS version --- diff --git a/makefile.wat b/makefile.wat new file mode 100644 index 0000000..f2a1cb6 --- /dev/null +++ b/makefile.wat @@ -0,0 +1,19 @@ +#****************************************************************************** +# @file Makefile.wat +#****************************************************************************** +SRCDIR ?= $(CURDIR) +VPATH := $(SRCDIR) + +CSRC := lib.c tar.c report.c +INCDIR := $(subst /,\,$(SRCDIR)) + +all: unzip.exe + +unzip.exe: $(CSRC) + + wcl -fe=$@ $^ + +clean: + + for /r %%f in (*.obj) do ( if exist %%f ( del /q %%f ) ) + if exist unzip.exe ( del /q unzip.exe ) diff --git a/report.c b/report.c index 8e128ef..b30b515 100755 --- a/report.c +++ b/report.c @@ -17,7 +17,11 @@ static int OriginalConsoleColor = -1; static void reset_console_color (void) { -#if defined (_WIN32) +#if defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__) + + fprintf (stderr, "\033[0m"); + +#elif defined (_WIN32) HANDLE hStdError = GetStdHandle (STD_ERROR_HANDLE); @@ -26,17 +30,17 @@ static void reset_console_color (void) { SetConsoleTextAttribute (hStdError, OriginalConsoleColor); OriginalConsoleColor = -1; -#else - - fprintf (stderr, "\033[0m"); - #endif } static void set_console_color (int color) { -#if defined (_WIN32) +#if defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__) + + fprintf (stderr, "\033[%dm", color); + +#elif defined (_WIN32) HANDLE hStdError = GetStdHandle (STD_ERROR_HANDLE); WORD wColor; @@ -56,10 +60,6 @@ static void set_console_color (int color) { wColor = (OriginalConsoleColor & 0xF0) + (color & 0xF); SetConsoleTextAttribute (hStdError, wColor); -#else - - fprintf (stderr, "\033[%dm", color); - #endif } diff --git a/tar.c b/tar.c index fd3f88b..80e51c3 100755 --- a/tar.c +++ b/tar.c @@ -867,6 +867,513 @@ static void extract_files (FILE *tarfp, char *root) { free (p2); +} +#elif defined (__WATCOMC__) +# include + +static int IsDirectory (const char *path) { + + struct SREGS sr = { 0 }; + union REGS r = { 0 }; + + char *temp = xstrdup (path); + unsigned len = strlen (temp); + + if (len > 3) { + + while (temp[len - 1] == '\\') { + temp[--len] = '\0'; + } + + } + + r.w.ax = 0x4300; + r.w.dx = FP_OFF (temp); + + sr.ds = FP_SEG (temp); + int86x (0x21, &r, &r, &sr); + + free (temp); + return (!(r.w.cflag & 1) && (r.w.cx & 0x10)); + +} + +int CreateDirectory (const char *path) { + + struct SREGS sr = { 0 }; + union REGS r = { 0 }; + + char *p = (char *) path; + + while (p && *p != '\0') { + + while (*p && *p == '\\') { + p++; + } + + if (*p == '\0') { break; } + + if ((p = strchr (p, '\\'))) { + *p = '\0'; + } + + r.w.ax = 0x3900; + r.w.dx = FP_OFF (path); + + sr.ds = FP_SEG (path); + int86x (0x21, &r, &r, &sr); + + if (r.w.cflag & 1) { + + r.w.ax = 0x4300; + r.w.dx = FP_OFF (path); + + sr.ds = FP_SEG (path); + int86x (0x21, &r, &r, &sr); + + if (r.w.cflag & 1) { + return 1; + } + + } + + if (p) { *p = '\\'; } + + } + + return 0; + +} + +static int FindFirstFile (const char *path) { + + struct SREGS sr = { 0 }; + union REGS r = { 0 }; + + char *temp = xstrdup (path); + unsigned len = strlen (temp); + + if (len > 3) { + + while (temp[len - 1] == '\\') { + temp[--len] = '\0'; + } + + } + + r.w.ax = 0x4E00; + r.w.cx = 0x30; + r.w.dx = FP_OFF (temp); + + sr.ds = FP_SEG (temp); + int86x (0x21, &r, &r, &sr); + + free (temp); + return (!(r.w.cflag & 1)); + +} + +static int SetDiskTransfer (void *buf) { + + struct SREGS sr = { 0 }; + union REGS r = { 0 }; + + r.w.ax = 0x1A00; + r.w.dx = FP_OFF (buf); + + sr.ds = FP_SEG (buf); + int86x (0x21, &r, &r, &sr); + + return (!(r.w.cflag & 1)); + +} + +static int FindNextFile (void) { + + struct SREGS sr = { 0 }; + union REGS r = { 0 }; + + r.w.ax = 0x4F00; + int86x (0x21, &r, &r, &sr); + + return (!(r.w.cflag & 1)); + +} + +static void add_entry (FILE *tarfp, char *root, const char *path) { + + struct tar_raw_header header; + + const char *p = path; + char *p2; + + unsigned long len, i; + int mode; + + if (isalpha ((int) p[0]) && p[1] == ':') { + p += 2; + } + + while (*p == '/' || *p == '\\') { + p++; + } + + if (root) { + + len = strlen (root); + + while (root[len - 1] == '/' || root[len - 1] == '\\') { + + root[len - 1] = '\0'; + len--; + + } + + for (i = 0; i < len; i++) { + + if (root[i] == '\\') { + root[i] = '/'; + } + + } + + p2 = xmalloc (len + 1); + sprintf (p2, "%s/", root); + + } else { + p2 = xstrdup (path); + } + + memset (&header, 0, sizeof (header)); + strcpy (header.name, p); + + memset (header.mtime, '0', 11); + sprintf (header.owner, "%07o", 0); + + if (state->mode) { + + int o1, o2, o3; + + o1 = state->mode[1] - '0'; + o2 = state->mode[2] - '0'; + o3 = state->mode[3] - '0'; + + mode = (o1 << 6) | (o2 << 3) | o3; + + } else { + mode = (IsDirectory (p2) ? 0775 : 0644); + } + + sprintf (header.mode, "%07o", mode); + + if (IsDirectory (p2)) { + + unsigned char dta[128] = { 0 }; + char *subpath, *filename; + + memset (header.size, '0', 11); + header.type = '5'; /* MTAR_TDIR */ + + if (header.name[strlen(p) - 1] != '/') { + header.name[strlen(p)] = '/'; + } + + sprintf (header.checksum, "%06o", checksum (&header)); + header.checksum[7] = ' '; + + if (fwrite (&header, 1, sizeof (header), tarfp) != sizeof (header)) { + report_at (program_name, 0, REPORT_ERROR, "failed to write header to '%s'", state->target); + } + + len = strlen (p2); + + if (p2[len - 1] == '/') { + + subpath = xmalloc (len + 5); + sprintf (subpath, "%s*.*", p2); + + } else { + + subpath = xmalloc (len + 6); + sprintf (subpath, "%s/*.*", p2); + + } + + if (!SetDiskTransfer (dta) || !FindFirstFile (subpath)) { + + free (subpath); + return; + + } + + free (subpath); + + do { + + filename = dta + 0x1E; + + if (filename[0] == '.' && (filename[1] == '\0' || (filename[1] == '.' && filename[2] == '\0'))) { + continue; + } + + len = strlen (path); + + if (path[len - 1] == '/') { + + len += (strlen (filename) + 1); + + if (!(subpath = malloc (len))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to allocate memory for '%s'", filename); + continue; + + } + + sprintf (subpath, "%s%s", path, filename); + + } else { + + len += (1 + strlen (filename) + 1); + + if (!(subpath = malloc (len))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to allocate memory for '%s'", filename); + continue; + + } + + sprintf (subpath, "%s/%s", path, filename); + + } + + add_entry (tarfp, root, subpath); + free (subpath); + + } while (FindNextFile ()); + + /*FindClose (hFind);*/ + + } else { + + FILE *fp; + + unsigned char *data; + uint64_t bytes, read; + + if (!(fp = fopen (p2, "r+b"))) { + + report_at (program_name, 0, REPORT_WARNING, "failed to open '%s' for reading", path); + goto _end; + + } + + fseek (fp, 0, SEEK_END); + bytes = ftell (fp); + + fseek (fp, 0, SEEK_SET); + + sprintf (header.size, "%011"I64_FMT"o", bytes); + header.type = '0'; /* MTAR_TREG */ + + sprintf (header.checksum, "%06o", checksum (&header)); + header.checksum[7] = ' '; + + if (fwrite (&header, 1, sizeof (header), tarfp) != sizeof (header)) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write header to '%s'", state->target); + fclose (fp); + + goto _end; + + } + + data = xmalloc (512); + + for (;;) { + + if (bytes == 0 || feof (fp)) { + break; + } + + read = (bytes > 512 ? 512 : bytes); + + if (fread (data, 1, read, fp) != read) { + + report_at (program_name, 0, REPORT_ERROR, "failed to read %lu bytes from %s", read, path); + break; + + } + + if (fwrite (data, 1, read, tarfp) != read) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write %lu bytes to %s", read, state->target); + break; + + } + + bytes -= read; + + } + + bytes = ftell (fp) % 512; + fclose (fp); + + if (bytes != 0) { + write_null_bytes (tarfp, 512 - bytes); + } + + } + +_end: + + free (p2); + +} + +static void extract_files (FILE *tarfp, char *root) { + + struct tar_raw_header header; + + char *path, *p2; + FILE *fp; + + unsigned long len, i; + + if (root) { + + len = strlen (root); + + while (root[len - 1] == '/' || root[len - 1] == '\\') { + + root[len - 1] = '\0'; + len--; + + } + + for (i = 0; i < len; i++) { + + if (root[i] == '\\') { + root[i] = '/'; + } + + } + + if (!CreateDirectory (root)) { + + report_at (program_name, 0, REPORT_ERROR, "failed to root directory %s", root); + return; + + } + + p2 = xmalloc (len + 1); + sprintf (p2, "%s/", root); + + } else { + p2 = xstrdup (""); + } + + for (;;) { + + if (feof (tarfp)) { + break; + } + + if (fread (&header, 1, sizeof (header), tarfp) != sizeof (header)) { + + report_at (program_name, 0, REPORT_ERROR, "failed to read archive header"); + break; + + } + + if (!header.name[0]) { + break; + } + + path = xmalloc (strlen (p2) + strlen (header.name) + 1); + sprintf (path, "%s%s", p2, header.name); + + printf ("extracting: %s\n", path); + + if (path[strlen (path) - 1] == '/') { + + path[strlen (path) - 1] = '\0'; + + if (!CreateDirectory (path)) { + + report_at (program_name, 0, REPORT_ERROR, "failed to create directory %s, %lx", path); + + free (path); + free (p2); + + return; + + } + + } else { + + unsigned long padding = 0, bytes, read; + unsigned char *data; + + if (!(fp = fopen (path, "w+b"))) { + + report_at (program_name, 0, REPORT_ERROR, "failed to create %s", path); + + free (path); + free (p2); + + return; + + } + + bytes = strtol (header.size, 0, 8); + + if ((bytes % 512) != 0) { + padding = 512 - (bytes % 512); + } + + data = xmalloc (512); + + for (;;) { + + memset (data, 0, 512); + + if (bytes == 0) { + break; + } + + read = (bytes > 512 ? 512 : bytes); + + if (fread (data, 1, read, tarfp) != read) { + + report_at (program_name, 0, REPORT_ERROR, "failed to read %lu bytes from %s", read, path); + break; + + } + + if (fwrite (data, 1, read, fp) != read) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write %lu bytes to %s", read, state->target); + break; + + } + + bytes -= read; + + } + + fseek (tarfp, padding, SEEK_CUR); + + free (data); + fclose (fp); + + } + + free (path); + + } + + free (p2); + } #endif