Initial commit
authorRobert Pengelly <robertapengelly@hotmail.com>
Thu, 20 Mar 2025 12:06:31 +0000 (12:06 +0000)
committerRobert Pengelly <robertapengelly@hotmail.com>
Thu, 20 Mar 2025 12:06:31 +0000 (12:06 +0000)
LICENSE [new file with mode: 0644]
Makefile.pdw [new file with mode: 0644]
Makefile.w32 [new file with mode: 0644]
README.md [new file with mode: 0644]
lib.c [new file with mode: 0644]
lib.h [new file with mode: 0644]
report.c [new file with mode: 0644]
report.h [new file with mode: 0644]
rm.c [new file with mode: 0644]
rm.h [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..fdddb29
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org>
diff --git a/Makefile.pdw b/Makefile.pdw
new file mode 100644 (file)
index 0000000..359bf8f
--- /dev/null
@@ -0,0 +1,23 @@
+#******************************************************************************
+# @file             Makefile.pdw
+#******************************************************************************
+AS=aswin
+CC=gccwin
+LD=ldwin
+
+COPTS=-S -O2 -fno-common -ansi -I. -I./include -I../pdos/pdpclib -I../pdos/src -D__WIN32__ -D__NOBIVA__ -D__PDOS__
+COBJ=lib.o report.o rm.o
+
+all: clean rm.exe
+
+rm.exe: $(COBJ)
+  $(LD) -s -o rm.exe ../pdos/pdpclib/w32start.o $(COBJ) ../pdos/pdpclib/msvcrt.a ../pdos/src/kernel32.a
+
+.c.o:
+  $(CC) $(COPTS) -o $*.s $<
+  $(AS) -o $@ $*.s
+  rm -f $*.s
+
+clean:
+  rm -f $(OBJ)
+  rm -f rm.exe
diff --git a/Makefile.w32 b/Makefile.w32
new file mode 100644 (file)
index 0000000..8996a60
--- /dev/null
@@ -0,0 +1,21 @@
+#******************************************************************************
+# @file             Makefile.w32
+#******************************************************************************
+SRCDIR              ?=  $(CURDIR)
+VPATH               :=  $(SRCDIR)
+
+CC                  :=  gcc
+CFLAGS              :=  -D_FILE_OFFSET_BITS=64 -Wall -Werror -Wextra -std=c90
+
+CSRC                :=  lib.c report.c rm.c
+
+all: rm.exe
+
+clean:
+
+       if exist rm.exe ( del /q rm.exe )
+       if exist rm ( del /q rm )
+
+rm.exe: $(CSRC)
+
+       $(CC) $(CFLAGS) -o $@ $^
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..61d9f29
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+## Licesne
+
+    All source code is Public Domain.
+
+## Obtain the source code
+
+    git clone https://git.candlhat.org/rm.git
+
+## Building
+
+    Windows:
+    
+        Make sure you have mingw installed and the location within your PATH variable
+        then run mingw32-make.exe -f Makefile.w32.
diff --git a/lib.c b/lib.c
new file mode 100644 (file)
index 0000000..284ad74
--- /dev/null
+++ b/lib.c
@@ -0,0 +1,156 @@
+/******************************************************************************
+ * @file            lib.c
+ *****************************************************************************/
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <string.h>
+
+#include    "rm.h"
+#include    "lib.h"
+#include    "report.h"
+
+static void print_usage (void) {
+
+    if (program_name) {
+        fprintf (stderr, "Usage: %s [options] file...\n\n", program_name);
+    }
+
+}
+
+static void dynarray_add (void *ptab, long *nb_ptr, void *data) {
+
+    long nb, nb_alloc;
+    void **pp;
+    
+    nb = *nb_ptr;
+    pp = *(void ***) ptab;
+    
+    if ((nb & (nb - 1)) == 0) {
+    
+        if (!nb) {
+            nb_alloc = 1;
+        } else {
+            nb_alloc = nb * 2;
+        }
+        
+        pp = xrealloc (pp, nb_alloc * sizeof (void *));
+        *(void ***) ptab = pp;
+    
+    }
+    
+    pp[nb++] = data;
+    *nb_ptr = nb;
+
+}
+
+char *xstrdup (const char *__p) {
+
+    char *p = xmalloc (strlen (__p) + 1);
+    
+    strcpy (p, __p);
+    return p;
+
+}
+
+void parse_args (int argc, char **argv, int optind) {
+
+    const char *r;
+    
+    if (argc <= optind) {
+    
+        print_usage ();
+        exit (EXIT_SUCCESS);
+    
+    }
+    
+    r = argv[optind++];
+    
+check_options:
+    
+    if (r[0] == '-') {
+        ++r;
+    }
+    
+    while (*r != '\0') {
+    
+        char ch = *r++;
+        
+        if (ch == 'f') {
+        
+            state->fflag++;
+            continue;
+        
+        }
+        
+        if (ch == 'i') {
+        
+            state->iflag++;
+            continue;
+        
+        }
+        
+        if (ch == 'r') {
+        
+            state->rflag++;
+            continue;
+        
+        }
+        
+        report_at (program_name, 0, REPORT_ERROR, "invalid option -- '%c'", ch);
+        
+        print_usage ();
+        exit (EXIT_FAILURE);
+    
+    }
+    
+    if ((r = argv[optind])) {
+    
+        if (*r == '-') {
+            goto check_options;
+        }
+    
+    }
+    
+    if (optind >= argc) {
+    
+        print_usage ();
+        exit (EXIT_FAILURE);
+    
+    }
+    
+    while (optind < argc) {
+        dynarray_add (&state->files, &state->nb_files, xstrdup (argv[optind++]));
+    }
+
+}
+
+void *xmalloc (unsigned long __size) {
+
+    void *ptr = malloc (__size);
+    
+    if (!ptr && __size) {
+    
+        report_at (program_name, 0, REPORT_ERROR, "memory full (malloc)");
+        exit (EXIT_FAILURE);
+    
+    }
+    
+    memset (ptr, 0, __size);
+    return ptr;
+
+}
+
+void *xrealloc (void *__ptr, unsigned long __size) {
+
+    void *ptr = realloc (__ptr, __size);
+    
+    if (!ptr && __size) {
+    
+        report_at (program_name, 0, REPORT_ERROR, "memory full (realloc)");
+        exit (EXIT_FAILURE);
+    
+    }
+    
+    return ptr;
+
+}
diff --git a/lib.h b/lib.h
new file mode 100644 (file)
index 0000000..ec8cb8b
--- /dev/null
+++ b/lib.h
@@ -0,0 +1,13 @@
+/******************************************************************************
+ * @file            lib.h
+ *****************************************************************************/
+#ifndef     _LIB_H
+#define     _LIB_H
+
+char *xstrdup (const char *__p);
+void parse_args (int argc, char **argv, int optind);
+
+void *xmalloc (unsigned long __size);
+void *xrealloc (void *__ptr, unsigned long __size);
+
+#endif      /* _LIB_H */
diff --git a/report.c b/report.c
new file mode 100644 (file)
index 0000000..fb010ce
--- /dev/null
+++ b/report.c
@@ -0,0 +1,149 @@
+/******************************************************************************
+ * @file            report.c
+ *****************************************************************************/
+#include    <stdarg.h>
+#include    <stdio.h>
+#include    <string.h>
+
+#include    "report.h"
+unsigned int errors = 0;
+
+#ifndef     __PDOS__
+#if     defined (_WIN32)
+# include   <windows.h>
+static int OriginalConsoleColor = -1;
+#endif
+
+static void reset_console_color (void) {
+
+#if     defined (_WIN32)
+
+    HANDLE hStdError = GetStdHandle (STD_ERROR_HANDLE);
+    
+    if (OriginalConsoleColor == -1) { return; }
+    
+    SetConsoleTextAttribute (hStdError, OriginalConsoleColor);
+    OriginalConsoleColor = -1;
+
+#else
+
+    fprintf (stderr, "\033[0m");
+
+#endif
+
+}
+
+static void set_console_color (int color) {
+
+#if     defined (_WIN32)
+
+    HANDLE hStdError = GetStdHandle (STD_ERROR_HANDLE);
+    WORD wColor;
+    
+    if (OriginalConsoleColor == -1) {
+    
+        CONSOLE_SCREEN_BUFFER_INFO csbi;
+        
+        if (!GetConsoleScreenBufferInfo (hStdError, &csbi)) {
+            return;
+        }
+        
+        OriginalConsoleColor = csbi.wAttributes;
+    
+    }
+    
+    wColor = (OriginalConsoleColor & 0xF0) + (color & 0xF);
+    SetConsoleTextAttribute (hStdError, wColor);
+
+#else
+
+    fprintf (stderr, "\033[%dm", color);
+
+#endif
+
+}
+#endif
+
+static void output_message (const char *filename, unsigned int lineno, unsigned int idx, int type, const char *fmt, va_list ap) {
+
+    if (filename) {
+    
+        if (lineno == 0) {
+            fprintf (stderr, "%s: ", filename);
+        } else {
+            fprintf (stderr, "%s:", filename);
+        }
+    
+    }
+    
+    if (lineno > 0) {
+    
+        if (idx == 0) {
+            fprintf (stderr, "%u: ", lineno);
+        } else {
+            fprintf (stderr, "%u:", lineno);
+        }
+    
+    }
+    
+    if (idx > 0) {
+        fprintf (stderr, "%u: ", idx);
+    }
+    
+    if (type == REPORT_ERROR || type == REPORT_FATAL_ERROR) {
+    
+#ifndef     __PDOS__
+        set_console_color (COLOR_ERROR);
+#endif
+        
+        if (type == REPORT_ERROR) {
+            fprintf (stderr, "error:");
+        } else {
+            fprintf (stderr, "fatal error:");
+        }
+    
+    } else if (type == REPORT_INTERNAL_ERROR) {
+    
+#ifndef     __PDOS__
+        set_console_color (COLOR_INTERNAL_ERROR);
+#endif
+        
+        fprintf (stderr, "internal error:");
+    
+    } else if (type == REPORT_WARNING) {
+    
+#ifndef     __PDOS__
+        set_console_color (COLOR_WARNING);
+#endif
+        
+        fprintf (stderr, "warning:");
+    
+    }
+    
+#ifndef     __PDOS__
+    reset_console_color ();
+#endif
+    
+    fprintf (stderr, " ");
+    vfprintf (stderr, fmt, ap);
+    fprintf (stderr, "\n");
+    
+    if (type != REPORT_WARNING) {
+        ++errors;
+    }
+
+}
+
+unsigned int get_error_count (void) {
+    return errors;
+}
+
+void report_at (const char *filename, unsigned int lineno, int type, const char *fmt, ...) {
+
+    va_list ap;
+    
+    va_start (ap, fmt);
+    output_message (filename, lineno, 0, type, fmt, ap);
+    va_end (ap);
+
+}
diff --git a/report.h b/report.h
new file mode 100644 (file)
index 0000000..8e694dd
--- /dev/null
+++ b/report.h
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * @file            report.h
+ *****************************************************************************/
+#ifndef     _REPORT_H
+#define     _REPORT_H
+
+#if     defined (_WIN32)
+# define    COLOR_ERROR                 12
+# define    COLOR_WARNING               13
+# define    COLOR_INTERNAL_ERROR        19
+#else
+# define    COLOR_ERROR                 91
+# define    COLOR_INTERNAL_ERROR        94
+# define    COLOR_WARNING               95
+#endif
+
+#define     REPORT_WARNING              0
+#define     REPORT_ERROR                1
+#define     REPORT_FATAL_ERROR          3
+#define     REPORT_INTERNAL_ERROR       4
+
+unsigned int get_error_count (void);
+void report_at (const char *filename, unsigned int lineno, int type, const char *fmt, ...);
+
+#endif      /* _REPORT_H */
diff --git a/rm.c b/rm.c
new file mode 100644 (file)
index 0000000..70b9b34
--- /dev/null
+++ b/rm.c
@@ -0,0 +1,166 @@
+/******************************************************************************
+ * @file            ar.c
+ *****************************************************************************/
+#include    <ctype.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <string.h>
+
+#include    "rm.h"
+#include    "lib.h"
+#include    "report.h"
+
+struct rm_state *state = 0;
+const char *program_name = 0;
+
+#if       defined (_WIN32)
+# include       <windows.h>
+
+static BOOL IsDirectory (LPCTSTR szPath) {
+
+    DWORD dwAttrib = GetFileAttributes (szPath);
+    return (dwAttrib != 0xFFFFFFFFL &&  (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
+
+}
+
+static void rm (const char *path) {
+
+    const char *p = path;
+    char *p2;
+    
+    unsigned long len;
+    
+    if (isalpha ((int) p[0]) && p[1] == ':') {
+        p += 2;
+    }
+    
+    while (*p == '/') {
+        p++;
+    }
+    
+    p2 = xstrdup (path);
+    
+    if (IsDirectory (p2)) {
+    
+        char *subpath, *filename;
+        
+        HANDLE hFind;
+        WIN32_FIND_DATA FindFileData;
+        
+        if (!state->rflag && !state->fflag) {
+        
+            report_at (program_name, 0, REPORT_ERROR, "cannot remove directoies without -r");
+            
+            free (p2);
+            return;
+        
+        }
+        
+        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 ((hFind = FindFirstFile (subpath, &FindFileData)) == INVALID_HANDLE_VALUE) {
+        
+            free (subpath);
+            return;
+        
+        }
+        
+        free (subpath);
+        
+        do {
+        
+            filename = FindFileData.cFileName;
+            
+            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);
+            
+            }
+            
+            rm (subpath);
+            free (subpath);
+        
+        } while (FindNextFile (hFind, &FindFileData) != 0);
+        
+        FindClose (hFind);
+    
+    } else {
+    
+        int ret = remove (p2);
+        
+        if (!state->fflag && ret) {
+            report_at (program_name, 0, REPORT_ERROR, "unable to remove %s", p2);
+        }
+    
+    }
+    
+    free (p2);
+
+}
+#endif
+
+int main (int argc, char **argv) {
+
+    long i;
+    
+    if (argc && *argv) {
+    
+        char *p;
+        program_name = *argv;
+        
+        if ((p = strrchr (program_name, '/')) || (p = strrchr (program_name, '\\'))) {
+            program_name = (p + 1);
+        }
+    
+    }
+    
+    state = xmalloc (sizeof (*state));
+    parse_args (argc, argv, 1);
+    
+    for (i = 0; i < state->nb_files; ++i) {
+        rm (state->files[i]);
+    }
+    
+    return (get_error_count () > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+
+}
diff --git a/rm.h b/rm.h
new file mode 100644 (file)
index 0000000..012d559
--- /dev/null
+++ b/rm.h
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * @file            rm.h
+ *****************************************************************************/
+#ifndef     _RM_H
+#define     _RM_H
+
+struct rm_state {
+
+    const char **files;
+    long nb_files;
+    
+    int fflag;
+    int iflag;
+    int rflag;
+
+};
+
+extern struct rm_state *state;
+extern const char *program_name;
+
+#endif      /* _RM_H */