util/mkshadow: delete ancient unused utility
authorJon Trulson <jon@radscan.com>
Wed, 27 Jun 2018 19:10:34 +0000 (13:10 -0600)
committerJon Trulson <jon@radscan.com>
Thu, 28 Jun 2018 03:58:04 +0000 (21:58 -0600)
cde/config/util/mkshadow/Imakefile [deleted file]
cde/config/util/mkshadow/README [deleted file]
cde/config/util/mkshadow/mkshadow.c [deleted file]
cde/config/util/mkshadow/savedir.c [deleted file]
cde/config/util/mkshadow/wildmat.c [deleted file]

diff --git a/cde/config/util/mkshadow/Imakefile b/cde/config/util/mkshadow/Imakefile
deleted file mode 100644 (file)
index 38b0614..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-XCOMM $XConsortium: Imakefile,v 1.1 94/04/13 18:44:40 rws Exp $
-           SRCS = mkshadow.c savedir.c wildmat.c
-           OBJS = mkshadow.o savedir.o wildmat.o
-
-ComplexProgramTarget(mkshadow)
diff --git a/cde/config/util/mkshadow/README b/cde/config/util/mkshadow/README
deleted file mode 100644 (file)
index eea4b8b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-The mkshadow programs makes a "shadow tree" of a directory tree.
-It logically copies all of the "MASTER" directory into ".".
-However, ordinary files, and RCS/SCCS directories are "copied"
-by creating a sybolic link to the corresponding file in MASTER.
-
-The wildmat.c file is by Rich Salz, and from comp.sources.misc, volume 17.
-The savedir.c file is lightly modified from the version written
-by David MacKenzie for GNU fileutils; the Free Software Foundation
-has graciously agreed to waive their usual copyright so this
-program can be distributed by the X Consortium.
-
-If you have problems compiling savedir.c, try setting the DIRENT make
-variable as suggested in the Makefile.
-
- * Usage: mkshadow [-X exclude_file] [-x exclude_pattern] ... MASTER
- * Makes the current directory be a "shadow copy" of MASTER.
- * Sort of like a recursive copy of MASTER to .
- * However, symbolic links are used instead of actually
- * copying (non-directory) files.
- * Also, directories named RCS or SCCS are shared (with a symbolic link).
- * Warning messages are printed for files (and directories) in .
- * that don't match a corresponding file in MASTER (though
- * symbolic links are silently removed).
- * Also, a warning message is printed for non-directory files
- * under . that are  not symbolic links.
- *
- * Files and directories can be excluded from the sharing
- * with the -X and -x flags. The flag `-x pattern' (or `-xpattern')
- * means that mkshadow should ignore any file whose name matches
- * the pattern. The pattern is a "globbing" pattern, i.e. the
- * characters *?[^-] are interpreted as by the shell.
- * If the pattern contains a '/' is is matched against the complete
- * current path (relative to '.'); otherwise, it is matched
- * against the last component of the path.
- * A `-X filename' flag means to read a set of exclusion patterns
- * from the named file, one pattern to a line.
-
-Author: Per Bothner. bothner@cygnus.com. November 1990, 1993.
diff --git a/cde/config/util/mkshadow/mkshadow.c b/cde/config/util/mkshadow/mkshadow.c
deleted file mode 100644 (file)
index ffb4ac5..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
-/* $XConsortium: mkshadow.c /main/2 1996/12/04 10:11:51 swick $ */
-/* mkshadow.c - make a "shadow copy" of a directory tree with symlinks.
-   Copyright 1990, 1993 Free Software Foundation, Inc.
-
-   Permission to use, copy, modify, and distribute this program for
-   any purpose and without fee is hereby granted, provided that this
-   copyright and permission notice appear on all copies, and that
-   notice be given that copying and distribution is by permission of
-   the Free Software Foundation.  The Free Software Foundation makes
-   no representations about the suitability of this software for any
-   purpose.  It is provided "as is" without expressed or implied
-   warranty.
-
-   (The FSF has modified its usual distribution terms, for this file,
-   as a courtesy to the X project.)  */
-
-/*
- * Usage: mkshadow [-X exclude_file] [-x exclude_pattern] ... MASTER [SHADOW]
- * Makes SHADOW be a "shadow copy" of MASTER.  SHADOW defaults to the current
- * directory. Sort of like a recursive copy of MASTER to SHADOW.
- * However, symbolic links are used instead of actually
- * copying (non-directory) files.
- * Also, directories named RCS or SCCS are shared (with a symbolic link).
- * Warning messages are printed for files (and directories) in .
- * that don't match a corresponding file in MASTER (though
- * symbolic links are silently removed).
- * Also, a warning message is printed for non-directory files
- * under SHADOW that are not symbolic links.
- *
- * Files and directories can be excluded from the sharing
- * with the -X and -x flags. The flag `-x pattern' (or `-xpattern')
- * means that mkshadow should ignore any file whose name matches
- * the pattern. The pattern is a "globbing" pattern, i.e. the
- * characters *?[^-] are interpreted as by the shell.
- * If the pattern contains a '/' is is matched against the complete
- * current path (relative to '.'); otherwise, it is matched
- * against the last component of the path.
- * A `-X filename' flag means to read a set of exclusion patterns
- * from the named file, one pattern to a line.
- *
- * Originally written by Per Bothner at University of Wisconsin-Madison,
- * inspired by the lndir script distributed with X11.
- * Modified by Per Bothner <bothner@cygnus.com> November 1993
- * to more-or-less follow Posix.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#ifdef BSD
-#include <strings.h>
-#define strchr index
-#else
-#include <string.h>
-#endif
-#include <sys/stat.h>
-#if defined(S_IFDIR) && !defined(S_ISDIR)
-#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#endif
-#if defined(S_IFLNK) && !defined(S_ISLNK)
-#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
-#endif
-#ifndef S_ISLNK
-#define lstat stat
-#endif
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 1024
-#endif
-#include <errno.h>
-#ifndef errno
-extern int errno;
-#endif
-
-extern char * savedir();
-
-fatal(msg)
-     char *msg;
-{
-    if (errno) perror(msg ? msg : "");
-    else if (msg) fprintf(stderr, "mkshadow: %s\n", msg);
-    exit(-1);
-}
-
-/* When handling symbolic links to relative directories,
- * we need to prepend "../" to the "source".
- * We preallocate MAX_DEPTH repetations of "../" using a simple trick.
- */
-#define MAX_DEPTH 20
-#define PREPEND_BUFFER_SIZE (MAX_DEPTH*3)
-char master_buffer[MAXPATHLEN+PREPEND_BUFFER_SIZE] =
-    "../../../../../../../../../../../../../../../../../../../../";
-/* The logical start of the master_buffer is defined by
- * master_start, which skips the fixed prepend area.
- */
-#define master_start (master_buffer+PREPEND_BUFFER_SIZE)
-char shadow_buffer[MAXPATHLEN];
-
-void bad_args(msg)
-{
-    if (msg) fprintf(stderr, "%s\n", msg);
-    fprintf (stderr, "usage: mkshadow [-X exclude_file] [-x exclude_pattern]");
-    fprintf (stderr, " master [shadow]\n");
-    exit(-1);
-}
-
-int exclude_count = 0;
-char **exclude_patterns = NULL;
-int exclude_limit = 0;
-
-void add_exclude(pattern)
-    char *pattern;
-{
-    if (exclude_limit == 0) {
-       exclude_limit = 100;
-       exclude_patterns = (char**)malloc(exclude_limit * sizeof(char*));
-    } else if (exclude_count + 1 >= exclude_limit) {
-       exclude_limit += 100;
-       exclude_patterns = (char**)realloc(exclude_patterns, 
-                                          exclude_limit * sizeof(char*));
-    }
-    exclude_patterns[exclude_count] = pattern;
-    exclude_count++;
-}
-
-void add_exclude_file(name)
-     char *name;
-{
-    char buf[MAXPATHLEN];
-    FILE *file = fopen(name, "r");
-    if (file == NULL) fatal("failed to find -X (exclude) file");
-    for (;;) {
-       int len;
-       char *str = fgets(buf, MAXPATHLEN, file);
-       if (str == NULL) break;
-       len = strlen(str);
-       if (len && str[len-1] == '\n') str[--len] = 0;
-       if (!len) continue;
-       str = (char*)malloc(len+1);
-       strcpy(str, buf);
-       add_exclude(str);
-    }
-    fclose(file);
-}
-
-main(argc, argv)
-     char **argv;
-{
-    char *master_name = NULL;
-    char *shadow_name = NULL;
-    int i;
-    for (i = 1; i < argc; i++) {
-       if (argv[i][0] == '-') {
-           switch(argv[i][1]) {
-             case 'X':
-               if (argv[i][2]) add_exclude_file(&argv[i][2]);
-               else if (++i >= argc) bad_args(NULL);
-               else add_exclude_file(argv[i]);
-               break;
-             case 'x':
-               if (argv[i][2]) add_exclude(&argv[i][2]);
-               else if (++i >= argc) bad_args(NULL);
-               else add_exclude(argv[i]);
-               break;
-             default:
-               bad_args(NULL);
-           }
-       } else if (master_name == NULL)
-           master_name = argv[i];
-       else if (shadow_name == NULL)
-           shadow_name = argv[i];
-       else bad_args (NULL);
-    }
-
-    if (master_name == NULL) bad_args(NULL);
-    if (shadow_name == NULL)
-       shadow_name = ".";
-    else if ((shadow_name[0] != '.' || shadow_name[1])
-            && master_name[0] != '/') {
-       fprintf(stderr, "Shadowing a relative directory pathname to a \n");
-       fprintf(stderr, "shadow other than '.' is not supported!\n");
-       exit(-1);
-    }
-    strcpy(shadow_buffer, shadow_name);
-    strcpy(master_start, master_name);
-    DoCopy(master_start, shadow_buffer, 0);
-    return 0;
-}
-
-int compare_strings(ptr1, ptr2)
-     char **ptr1, **ptr2;
-{
-    return strcmp(*ptr1, *ptr2);
-}
-
-void MakeLink(master, current, depth)
-     char *master;
-     char *current;
-     int depth;
-{
-    if (master[0] != '/') {
-       /* Source directory was specified with a relative pathname. */
-       if (master != master_start) {
-           fatal("Internal bug: bad string buffer use");
-       }
-       /* Pre-pend "../" depth times. This compensates for
-        * the directories we've entered. */
-       master -= 3 * depth;
-    }
-    if (symlink(master, current)) {
-       fprintf(stderr, "Failed to create symbolic link %s->%s\n",
-               current, master);
-       exit (-1);
-    }
-}
-
-
-/* Get a sorted NULL_terminator array of (char*) using 'names'
- * (created by save_dir) as data.
- */
-char ** get_name_pointers(names)
-     char *names;
-{
-    int n_names = 0;
-    int names_buf_size = 64;
-    char *namep;
-    char ** pointers = (char**)malloc(names_buf_size * sizeof(char*));
-    if (!names || !pointers) fatal("virtual memory exhausted");
-
-    for (namep = names; *namep; namep += strlen(namep) + 1) {
-       if (n_names + 1 >= names_buf_size) {
-           names_buf_size *= 2;
-           pointers = (char**)realloc(pointers,
-                                      names_buf_size * sizeof(char*));
-           if (!pointers) fatal("virtual memory exhausted");
-       }
-       pointers[n_names++] = namep;
-    }
-    pointers[n_names] = 0;
-    qsort(pointers, n_names, sizeof(char*), compare_strings);
-    return pointers;
-}
-
-/* Recursively shadow the directory whose name is in MASTER
- * (which is == MASTER_START) into the destination directory named CURRENT.
- */
-
-DoCopy(master, current, depth)
-     char *master; /* The source directory. */
-     char *current; /* The destination directory. */
-     int depth;
-{
-    struct stat stat_master, stat_current;
-    char **master_pointer, **current_pointer;
-    char **master_names, **current_names;
-    char *master_end, *current_end;
-    char *master_name_buf, *current_name_buf;
-    master_end = master + strlen(master);
-    current_end = current + strlen(current);
-
-    /* Get rid of terminal '/' */
-    if (master_end[-1] == '/' && master != master_end - 1)
-       *--master_end = 0;
-    if (current_end[-1] == '/' && current != current_end - 1)
-       *--current_end = 0;
-
-    if (depth >= MAX_DEPTH) {
-       fprintf(stderr,
-               "Nesting too deep (depth %d at %s). Probable circularity.\n",
-               depth, master);
-       exit(-1);
-    }
-
-    master_name_buf = savedir(master, 500);
-    if (master_name_buf == NULL) {
-       fprintf(stderr, "Not enough memory or no such directory: %s\n",
-               master);
-       exit(-1);
-    }
-    current_name_buf = savedir(current, 500);
-    if (current_name_buf == NULL) {
-       fprintf(stderr, "Not enough memory or no such directory: %s\n",
-               current);
-       exit(-1);
-    }
-
-    master_names = get_name_pointers(master_name_buf);
-    current_names = get_name_pointers(current_name_buf);
-
-    master_pointer = master_names;
-    current_pointer = current_names;
-    for (;;) {
-       int cmp, ipat;
-       int in_master, in_current;
-       char *cur_name;
-       if (*master_pointer == NULL && *current_pointer == NULL)
-           break;
-       if (*master_pointer == NULL) cmp = 1;
-       else if (*current_pointer == NULL) cmp = -1;
-       else cmp = strcmp(*master_pointer, *current_pointer);
-       if (cmp < 0) { /* file only exists in master directory */
-           in_master = 1; in_current = 0;
-       } else if (cmp == 0) { /* file exists in both directories */
-           in_master = 1; in_current = 1;
-       } else { /* file only exists in current directory */
-           in_current = 1; in_master = 0;
-       }
-       cur_name = in_master ? *master_pointer : *current_pointer;
-       sprintf(master_end, "/%s", cur_name);
-       sprintf(current_end, "/%s", cur_name);
-       for (ipat = 0; ipat < exclude_count; ipat++) {
-           char *pat = exclude_patterns[ipat];
-           char *cur;
-           if (strchr(pat, '/')) cur = current + 2; /* Skip initial "./" */
-           else cur = cur_name;
-           if (wildmat(cur, pat)) goto skip;
-       }
-       if (in_master)
-           if (lstat(master, &stat_master) != 0) fatal("stat failed");
-       if (in_current)
-           if (lstat(current, &stat_current) != 0) fatal("stat failed");
-       if (in_current && !in_master) {
-           if (S_ISLNK(stat_current.st_mode))
-               if (unlink(current)) {
-                   fprintf(stderr, "Failed to remove symbolic link %s.\n",
-                           current);
-               }
-               else
-                   fprintf(stderr, "Removed symbolic link %s.\n",
-                           current);
-           else {
-               fprintf(stderr,
-                       "The file %s does not exist in the master tree.\n",
-                       current);
-           }
-       }
-       else if (S_ISDIR(stat_master.st_mode)
-                && strcmp(cur_name, "RCS") != 0
-                && strcmp(cur_name, "SCCS") != 0) {
-           if (!in_current) {
-               if (mkdir(current, 0775)) fatal("mkdir failed");
-           }
-           else if (stat(current, &stat_current)) fatal("stat failed");
-           if (!in_current || stat_current.st_dev != stat_master.st_dev
-               || stat_current.st_ino != stat_master.st_ino)
-               DoCopy(master, current, depth+1);
-           else
-               fprintf(stderr, "Link %s is the same as directory %s.\n",
-                       current, master);
-       }
-       else {
-           if (!in_current)
-               MakeLink(master, current, depth);
-           else if (!S_ISLNK(stat_current.st_mode)) {
-               fprintf(stderr, "Existing file %s is not a symbolc link.\n",
-                       current);
-           } else {
-               if (stat(current, &stat_current) || stat(master, &stat_master))
-                   fatal("stat failed");
-               if (stat_current.st_dev != stat_master.st_dev
-                   || stat_current.st_ino != stat_master.st_ino) {
-                   fprintf(stderr, "Fixing incorrect symbolic link %s.\n",
-                           current);
-                   if (unlink(current)) {
-                       fprintf(stderr, "Failed to remove symbolic link %s.\n",
-                               current);
-                   }
-                   else
-                       MakeLink(master, current, depth);
-               }
-           }
-       }
-      skip:
-       if (in_master) master_pointer++;
-       if (in_current) current_pointer++;
-    }
-
-    free(master_names); free(current_names);
-    free(master_name_buf); free(current_name_buf);
-}
diff --git a/cde/config/util/mkshadow/savedir.c b/cde/config/util/mkshadow/savedir.c
deleted file mode 100644 (file)
index 009c849..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
-/* $XConsortium: savedir.c,v 1.1 94/04/13 18:26:54 rws Exp $ */
-/* savedir.c -- save the list of files in a directory in a string
-   Copyright 1990, 1993 Free Software Foundation, Inc.
-
-   Permission to use, copy, modify, and distribute this program for
-   any purpose and without fee is hereby granted, provided that this
-   copyright and permission notice appear on all copies, and that
-   notice be given that copying and distribution is by permission of
-   the Free Software Foundation.  The Free Software Foundation makes
-   no representations about the suitability of this software for any
-   purpose.  It is provided "as is" without expressed or implied
-   warranty.
-
-   (The FSF has modified its usual distribution terms, for this file,
-   as a courtesy to the X project.)  */
-
-/* Written by David MacKenzie <djm@ai.mit.edu>.
-   Modified to use <dirent.h> by default.  Per Bothner <bothner@cygnus.com>. */
-
-#include <sys/types.h>
-#if !defined(DIRECT) && !defined(BSD)
-#include <dirent.h>
-#define NLENGTH(direct) (strlen((direct)->d_name))
-#else
-#undef dirent
-#define dirent direct
-#define NLENGTH(direct) ((direct)->d_namlen)
-#ifdef BSD
-#include <sys/dir.h>
-#else
-#ifdef SYSNDIR
-#include <sys/ndir.h>
-#else
-#include <ndir.h>
-#endif
-#endif
-#endif
-
-#if defined(VOID_CLOSEDIR) || defined(BSD)
-/* Fake a return value. */
-#define CLOSEDIR(d) (closedir (d), 0)
-#else
-#define CLOSEDIR(d) closedir (d)
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#include <string.h>
-#else
-char *malloc ();
-char *realloc ();
-int strlen ();
-#ifndef NULL
-#define NULL 0
-#endif
-#endif
-
-char *stpcpy ();
-
-/* Return a freshly allocated string containing the filenames
-   in directory DIR, separated by '\0' characters;
-   the end is marked by two '\0' characters in a row.
-   NAME_SIZE is the number of bytes to initially allocate
-   for the string; it will be enlarged as needed.
-   Return NULL if DIR cannot be opened or if out of memory. */
-
-char *
-savedir (dir, name_size)
-     char *dir;
-     unsigned name_size;
-{
-  DIR *dirp;
-  struct dirent *dp;
-  char *name_space;
-  char *namep;
-
-  dirp = opendir (dir);
-  if (dirp == NULL)
-    return NULL;
-
-  name_space = (char *) malloc (name_size);
-  if (name_space == NULL)
-    {
-      closedir (dirp);
-      return NULL;
-    }
-  namep = name_space;
-
-  while ((dp = readdir (dirp)) != NULL)
-    {
-      /* Skip "." and ".." (some NFS filesystems' directories lack them). */
-      if (dp->d_name[0] != '.'
-         || (dp->d_name[1] != '\0'
-             && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
-       {
-         unsigned size_needed = (namep - name_space) + NLENGTH (dp) + 2;
-
-         if (size_needed > name_size)
-           {
-             char *new_name_space;
-
-             while (size_needed > name_size)
-               name_size += 1024;
-
-             new_name_space = realloc (name_space, name_size);
-             if (new_name_space == NULL)
-               {
-                 closedir (dirp);
-                 return NULL;
-               }
-             namep += new_name_space - name_space;
-             name_space = new_name_space;
-           }
-         strcpy (namep, dp->d_name);
-         namep += strlen (namep) + 1;
-       }
-    }
-  *namep = '\0';
-  if (CLOSEDIR (dirp))
-    {
-      free (name_space);
-      return NULL;
-    }
-  return name_space;
-}
diff --git a/cde/config/util/mkshadow/wildmat.c b/cde/config/util/mkshadow/wildmat.c
deleted file mode 100644 (file)
index e6b1def..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
-/* $XConsortium: wildmat.c,v 1.2 94/04/13 18:40:59 rws Exp $ */
-/*
-**
-**  Do shell-style pattern matching for ?, \, [], and * characters.
-**  Might not be robust in face of malformed patterns; e.g., "foo[a-"
-**  could cause a segmentation violation.  It is 8bit clean.
-**
-**  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
-**  Rich $alz is now <rsalz@bbn.com>.
-**  April, 1991:  Replaced mutually-recursive calls with in-line code
-**  for the star character.
-**
-**  Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code.
-**  This can greatly speed up failing wildcard patterns.  For example:
-**     pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
-**     text 1:  -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
-**     text 2:  -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1
-**  Text 1 matches with 51 calls, while text 2 fails with 54 calls.  Without
-**  the ABORT, then it takes 22310 calls to fail.  Ugh.  The following
-**  explanation is from Lars:
-**  The precondition that must be fulfilled is that DoMatch will consume
-**  at least one character in text.  This is true if *p is neither '*' nor
-**  '\0'.)  The last return has ABORT instead of FALSE to avoid quadratic
-**  behaviour in cases like pattern "*a*b*c*d" with text "abcxxxxx".  With
-**  FALSE, each star-loop has to run to the end of the text; with ABORT
-**  only the last one does.
-**
-**  Once the control of one instance of DoMatch enters the star-loop, that
-**  instance will return either TRUE or ABORT, and any calling instance
-**  will therefore return immediately after (without calling recursively
-**  again).  In effect, only one star-loop is ever active.  It would be
-**  possible to modify the code to maintain this context explicitly,
-**  eliminating all recursive calls at the cost of some complication and
-**  loss of clarity (and the ABORT stuff seems to be unclear enough by
-**  itself).  I think it would be unwise to try to get this into a
-**  released version unless you have a good test data base to try it out
-**  on.
-*/
-
-#define TRUE                   1
-#define FALSE                  0
-#define ABORT                  -1
-
-
-    /* What character marks an inverted character class? */
-#define NEGATE_CLASS           '^'
-    /* Is "*" a common pattern? */
-#define OPTIMIZE_JUST_STAR
-    /* Do tar(1) matching rules, which ignore a trailing slash? */
-#undef MATCH_TAR_PATTERN
-
-
-/*
-**  Match text and p, return TRUE, FALSE, or ABORT.
-*/
-static int
-DoMatch(text, p)
-    register char      *text;
-    register char      *p;
-{
-    register int       last;
-    register int       matched;
-    register int       reverse;
-
-    for ( ; *p; text++, p++) {
-       if (*text == '\0' && *p != '*')
-           return ABORT;
-       switch (*p) {
-       case '\\':
-           /* Literal match with following character. */
-           p++;
-           /* FALLTHROUGH */
-       default:
-           if (*text != *p)
-               return FALSE;
-           continue;
-       case '?':
-           /* Match anything. */
-           continue;
-       case '*':
-           while (*++p == '*')
-               /* Consecutive stars act just like one. */
-               continue;
-           if (*p == '\0')
-               /* Trailing star matches everything. */
-               return TRUE;
-           while (*text)
-               if ((matched = DoMatch(text++, p)) != FALSE)
-                   return matched;
-           return ABORT;
-       case '[':
-           reverse = p[1] == NEGATE_CLASS ? TRUE : FALSE;
-           if (reverse)
-               /* Inverted character class. */
-               p++;
-           for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
-               /* This next line requires a good C compiler. */
-               if (*p == '-' ? *text <= *++p && *text >= last : *text == *p)
-                   matched = TRUE;
-           if (matched == reverse)
-               return FALSE;
-           continue;
-       }
-    }
-
-#ifdef MATCH_TAR_PATTERN
-    if (*text == '/')
-       return TRUE;
-#endif /* MATCH_TAR_ATTERN */
-    return *text == '\0';
-}
-
-
-/*
-**  User-level routine.  Returns TRUE or FALSE.
-*/
-int
-wildmat(text, p)
-    char       *text;
-    char       *p;
-{
-#ifdef OPTIMIZE_JUST_STAR
-    if (p[0] == '*' && p[1] == '\0')
-       return TRUE;
-#endif /* OPTIMIZE_JUST_STAR */
-    return DoMatch(text, p) == TRUE;
-}
-
-\f
-
-#ifdef TEST
-#include <stdio.h>
-
-/* Yes, we use gets not fgets.  Sue me. */
-extern char    *gets();
-
-
-main()
-{
-    char        p[80];
-    char        text[80];
-
-    printf("Wildmat tester.  Enter pattern, then strings to test.\n");
-    printf("A blank line gets prompts for a new pattern; a blank pattern\n");
-    printf("exits the program.\n");
-
-    for ( ; ; ) {
-       printf("\nEnter pattern:  ");
-       (void)fflush(stdout);
-       if (gets(p) == NULL || p[0] == '\0')
-           break;
-       for ( ; ; ) {
-           printf("Enter text:  ");
-           (void)fflush(stdout);
-           if (gets(text) == NULL)
-               exit(0);
-           if (text[0] == '\0')
-               /* Blank line; go back and get a new pattern. */
-               break;
-           printf("      %s\n", wildmat(text, p) ? "YES" : "NO");
-       }
-    }
-
-    exit(0);
-    /* NOTREACHED */
-}
-#endif /* TEST */