mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
util/mkshadow: delete ancient unused utility
This commit is contained in:
parent
29ea5f794d
commit
4aa9392e98
5 changed files with 0 additions and 779 deletions
|
@ -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)
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#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 */
|
Loading…
Reference in a new issue