From 26aaccb0e954970d22da4dc9ef5d5b5c4f27c260 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Pinard?= Date: Wed, 16 Nov 1994 02:57:06 +0000 Subject: [PATCH] Initial revision --- src/configure.in | 49 ++++++++++ src/names.c | 156 ++++++++++++++---------------- src/open3.h | 20 ++-- src/tcexparg.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 372 insertions(+), 94 deletions(-) create mode 100644 src/configure.in create mode 100644 src/tcexparg.c diff --git a/src/configure.in b/src/configure.in new file mode 100644 index 0000000..5a169cf --- /dev/null +++ b/src/configure.in @@ -0,0 +1,49 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(tar.h) +PROGS="tar" +AC_SUBST(PROGS)dnl +AC_PROG_CC +AC_PROG_CPP +AC_GCC_TRADITIONAL +AC_PROG_INSTALL +AC_PROG_YACC +AC_AIX +AC_MINIX +AC_ISC_POSIX +AC_RETSIGTYPE +AC_SIZE_T +AC_MAJOR_HEADER +AC_DIR_HEADER +# The 3-argument open happens to go along with the O_* defines, +# which are easier to check for. +AC_HEADER_CHECK(fcntl.h, open_header=fcntl.h, open_header=sys/file.h) +AC_COMPILE_CHECK(3-argument open, +[#include <$open_header>], [int x = O_RDONLY;], , AC_DEFINE(EMUL_OPEN3)) +AC_REMOTE_TAPE +AC_RSH +AC_STDC_HEADERS +AC_UNISTD_H +AC_HEADER_CHECK(limits.h, AC_DEFINE(HAVE_LIMITS_H)) +AC_USG +echo checking default archive +# This is likely to guess wrong, but it's not very important. +for dev in rmt8 rmt0 rmt0h rct0 rst0 tape rct/c7d0s2 +do + if test -n "`ls /dev/$dev 2>/dev/null`"; then + DEF_AR_FILE=/dev/$dev + break + fi +done +if test -z "$DEF_AR_FILE"; then + DEF_AR_FILE=- +fi + +AC_SUBST(DEF_AR_FILE)dnl +AC_HAVE_FUNCS(strstr valloc mkdir mknod rename ftruncate ftime) +AC_VPRINTF +AC_ALLOCA +echo checking for BSD +test -f /vmunix && AC_DEFINE(BSD42) + +AC_XENIX_DIR +AC_OUTPUT(Makefile) diff --git a/src/names.c b/src/names.c index 0de6a88..26a8e63 100644 --- a/src/names.c +++ b/src/names.c @@ -1,5 +1,5 @@ /* Look up user and/or group names. - Copyright (C) 1988, 1992 Free Software Foundation + Copyright (C) 1988 Free Software Foundation This file is part of GNU Tar. @@ -22,25 +22,26 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * * This file should be modified for non-unix systems to do something * reasonable. - */ - + * + * @(#)names.c 1.3 10/30/87 - gnu + */ #include #include "tar.h" -#include "port.h" + +extern char *strncpy(); #ifndef NONAMES /* Whole module goes away if NONAMES defined. Otherwise... */ -#include #include #include -static int saveuid = -993; -static char saveuname[TUNMLEN]; -static int my_uid = -993; +static int saveuid = -993; +static char saveuname[TUNMLEN]; +static int my_uid = -993; -static int savegid = -993; -static char savegname[TGNMLEN]; -static int my_gid = -993; +static int savegid = -993; +static char savegname[TGNMLEN]; +static int my_gid = -993; #define myuid ( my_uid < 0? (my_uid = getuid()): my_uid ) #define mygid ( my_gid < 0? (my_gid = getgid()): my_gid ) @@ -54,96 +55,81 @@ static int my_gid = -993; * pages" code, roughly doubling the program size. Thanks guys. */ void -finduname (uname, uid) - char uname[TUNMLEN]; - int uid; +finduname(uname, uid) + char uname[TUNMLEN]; + int uid; { - struct passwd *pw; -#ifndef HAVE_GETPWUID - extern struct passwd *getpwuid (); -#endif - - if (uid != saveuid) - { - saveuid = uid; - saveuname[0] = '\0'; - pw = getpwuid (uid); - if (pw) - strncpy (saveuname, pw->pw_name, TUNMLEN); - } - strncpy (uname, saveuname, TUNMLEN); + struct passwd *pw; + extern struct passwd *getpwuid (); + + if (uid != saveuid) { + saveuid = uid; + saveuname[0] = '\0'; + pw = getpwuid(uid); + if (pw) + strncpy(saveuname, pw->pw_name, TUNMLEN); + } + strncpy(uname, saveuname, TUNMLEN); } int -finduid (uname) - char uname[TUNMLEN]; +finduid(uname) + char uname[TUNMLEN]; { - struct passwd *pw; - extern struct passwd *getpwnam (); - - if (uname[0] != saveuname[0] /* Quick test w/o proc call */ - || 0 != strncmp (uname, saveuname, TUNMLEN)) - { - strncpy (saveuname, uname, TUNMLEN); - pw = getpwnam (uname); - if (pw) - { - saveuid = pw->pw_uid; + struct passwd *pw; + extern struct passwd *getpwnam(); + + if (uname[0] != saveuname[0] /* Quick test w/o proc call */ + || 0!=strncmp(uname, saveuname, TUNMLEN)) { + strncpy(saveuname, uname, TUNMLEN); + pw = getpwnam(uname); + if (pw) { + saveuid = pw->pw_uid; + } else { + saveuid = myuid; + } } - else - { - saveuid = myuid; - } - } - return saveuid; + return saveuid; } void -findgname (gname, gid) - char gname[TGNMLEN]; - int gid; +findgname(gname, gid) + char gname[TGNMLEN]; + int gid; { - struct group *gr; -#ifndef HAVE_GETGRGID - extern struct group *getgrgid (); -#endif - - if (gid != savegid) - { - savegid = gid; - savegname[0] = '\0'; - (void) setgrent (); - gr = getgrgid (gid); - if (gr) - strncpy (savegname, gr->gr_name, TGNMLEN); - } - (void) strncpy (gname, savegname, TGNMLEN); + struct group *gr; + extern struct group *getgrgid (); + + if (gid != savegid) { + savegid = gid; + savegname[0] = '\0'; + (void)setgrent(); + gr = getgrgid(gid); + if (gr) + strncpy(savegname, gr->gr_name, TGNMLEN); + } + (void) strncpy(gname, savegname, TGNMLEN); } int -findgid (gname) - char gname[TUNMLEN]; +findgid(gname) + char gname[TUNMLEN]; { - struct group *gr; - extern struct group *getgrnam (); - - if (gname[0] != savegname[0] /* Quick test w/o proc call */ - || 0 != strncmp (gname, savegname, TUNMLEN)) - { - strncpy (savegname, gname, TUNMLEN); - gr = getgrnam (gname); - if (gr) - { - savegid = gr->gr_gid; - } - else - { - savegid = mygid; + struct group *gr; + extern struct group *getgrnam(); + + if (gname[0] != savegname[0] /* Quick test w/o proc call */ + || 0!=strncmp(gname, savegname, TUNMLEN)) { + strncpy(savegname, gname, TUNMLEN); + gr = getgrnam(gname); + if (gr) { + savegid = gr->gr_gid; + } else { + savegid = mygid; + } } - } - return savegid; + return savegid; } - #endif diff --git a/src/open3.h b/src/open3.h index c1c0e59..e3e925f 100644 --- a/src/open3.h +++ b/src/open3.h @@ -18,11 +18,13 @@ along with GNU Tar; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* + * @(#)open3.h 1.4 87/11/11 + * * open3.h -- #defines for the various flags for the Sys V style 3-argument * open() call. On BSD or System 5, the system already has this in an * include file. This file is needed for V7 and MINIX systems for the * benefit of open3() in port.c, a routine that emulates the 3-argument - * call using system calls available on V7/MINIX. + * call using system calls available on V7/MINIX. * * This file is needed by PD tar even if we aren't using the * emulator, since the #defines for O_WRONLY, etc. are used in @@ -38,9 +40,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ /* Only one of the next three should be specified */ -#define O_RDONLY 0 /* only allow read */ -#define O_WRONLY 1 /* only allow write */ -#define O_RDWR 2 /* both are allowed */ +#define O_RDONLY 0 /* only allow read */ +#define O_WRONLY 1 /* only allow write */ +#define O_RDWR 2 /* both are allowed */ /* The rest of these can be OR-ed in to the above. */ /* @@ -50,13 +52,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * it defined. */ #ifndef O_NDELAY -#define O_NDELAY 4 /* don't block on opening devices that would +#define O_NDELAY 4 /* don't block on opening devices that would * block on open -- ignored by emulator. */ #endif -#define O_CREAT 8 /* create file if needed */ -#define O_EXCL 16 /* file cannot already exist */ -#define O_TRUNC 32 /* truncate file on open */ -#define O_APPEND 64 /* always write at end of file -- ignored by emul */ +#define O_CREAT 8 /* create file if needed */ +#define O_EXCL 16 /* file cannot already exist */ +#define O_TRUNC 32 /* truncate file on open */ +#define O_APPEND 64 /* always write at end of file -- ignored by emul */ #ifdef EMUL_OPEN3 /* diff --git a/src/tcexparg.c b/src/tcexparg.c new file mode 100644 index 0000000..f319dd9 --- /dev/null +++ b/src/tcexparg.c @@ -0,0 +1,241 @@ +/* tcexparg.c - Unix-style command line wildcards for Turbo C 2.0 + + This file is in the public domain. + + Compile your main program with -Dmain=_main and link with this file. + + After that, it is just as if the operating system had expanded the + arguments, except that they are not sorted. The program name and all + arguments that are expanded from wildcards are lowercased. + + Syntax for wildcards: + * Matches zero or more of any character (except a '.' at + the beginning of a name). + ? Matches any single character. + [r3z] Matches 'r', '3', or 'z'. + [a-d] Matches a single character in the range 'a' through 'd'. + [!a-d] Matches any single character except a character in the + range 'a' through 'd'. + + The period between the filename root and its extension need not be + given explicitly. Thus, the pattern `a*e' will match 'abacus.exe' + and 'axyz.e' as well as 'apple'. Comparisons are not case sensitive. + + Authors: + The expargs code is a modification of wildcard expansion code + written for Turbo C 1.0 by + Richard Hargrove + Texas Instruments, Inc. + P.O. Box 869305, m/s 8473 + Plano, Texas 75086 + 214/575-4128 + and posted to USENET in September, 1987. + + The wild_match code was written by Rich Salz, rsalz@bbn.com, + posted to net.sources in November, 1986. + + The code connecting the two is by Mike Slomin, bellcore!lcuxa!mike2, + posted to comp.sys.ibm.pc in November, 1988. + + Major performance enhancements and bug fixes, and source cleanup, + by David MacKenzie, djm@ai.mit.edu. */ + +#include +#include +#include +#include +#include + +/* Number of new arguments to allocate space for at a time. */ +#define ARGS_INCREMENT 10 + +/* The name this program was run with, for error messages. */ +static char *program_name; + +static char **grow_argv (char **new_argv, int new_argc); +static void fatal_error (const char *message); + +int wild_match (char *string, char *pattern); +char *basename (char *path); + +char **expargs (int *, char **); + +#ifdef main +#undef main +#endif + +int +main (int argc, char **argv, char **envp) +{ + argv = expargs (&argc, argv); + return _main (argc, argv, envp); +} + +char ** +expargs (int *pargc, char **argv) +{ + char path[MAXPATH + 1]; + char **new_argv; + struct ffblk block; + char *path_base; + char *arg_base; + int argind; + int new_argc; + int path_length; + int matched; + + program_name = argv[0]; + if (program_name && *program_name) + strlwr (program_name); + new_argv = grow_argv (NULL, 0); + new_argv[0] = argv[0]; + new_argc = 1; + + for (argind = 1; argind < *pargc; ++argind) + { + matched = 0; + if (strpbrk (argv[argind], "?*[") != NULL) + { + strncpy (path, argv[argind], MAXPATH - 3); + path_base = basename (path); + strcpy (path_base, "*.*"); + arg_base = argv[argind] + (path_base - path); + + if (!findfirst (path, &block, FA_DIREC)) + { + strlwr (path); + do + { + /* Only match "." and ".." explicitly. */ + if (*block.ff_name == '.' && *arg_base != '.') + continue; + path_length = stpcpy (path_base, block.ff_name) - path + 1; + strlwr (path_base); + if (wild_match (path, argv[argind])) + { + matched = 1; + new_argv[new_argc] = (char *) malloc (path_length); + if (new_argv[new_argc] == NULL) + fatal_error ("memory exhausted"); + strcpy (new_argv[new_argc++], path); + new_argv = grow_argv (new_argv, new_argc); + } + } + while (!findnext (&block)); + } + } + if (matched == 0) + new_argv[new_argc++] = argv[argind]; + new_argv = grow_argv (new_argv, new_argc); + } + + *pargc = new_argc; + new_argv[new_argc] = NULL; + return &new_argv[0]; +} + +/* Return a pointer to the last element of PATH. */ + +char * +basename (char *path) +{ + char *tail; + + for (tail = path; *path; ++path) + if (*path == ':' || *path == '\\') + tail = path + 1; + return tail; +} + +static char ** +grow_argv (char **new_argv, int new_argc) +{ + if (new_argc % ARGS_INCREMENT == 0) + { + new_argv = (char **) realloc + (new_argv, sizeof (char *) * (new_argc + ARGS_INCREMENT)); + if (new_argv == NULL) + fatal_error ("memory exhausted"); + } + return new_argv; +} + +static void +fatal_error (const char *message) +{ + putc ('\n', stderr); + if (program_name && *program_name) + { + fputs (program_name, stderr); + fputs (": ", stderr); + } + fputs (message, stderr); + putc ('\n', stderr); + exit (1); +} + +/* Shell-style pattern matching for ?, \, [], and * characters. + I'm putting this replacement in the public domain. + + Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. */ + +/* The character that inverts a character class; '!' or '^'. */ +#define INVERT '!' + +static int star (char *string, char *pattern); + +/* Return nonzero if `string' matches Unix-style wildcard pattern + `pattern'; zero if not. */ + +int +wild_match (char *string, char *pattern) +{ + int prev; /* Previous character in character class. */ + int matched; /* If 1, character class has been matched. */ + int reverse; /* If 1, character class is inverted. */ + + for (; *pattern; string++, pattern++) + switch (*pattern) + { + case '\\': + /* Literal match with following character; fall through. */ + pattern++; + default: + if (*string != *pattern) + return 0; + continue; + case '?': + /* Match anything. */ + if (*string == '\0') + return 0; + continue; + case '*': + /* Trailing star matches everything. */ + return *++pattern ? star (string, pattern) : 1; + case '[': + /* Check for inverse character class. */ + reverse = pattern[1] == INVERT; + if (reverse) + pattern++; + for (prev = 256, matched = 0; *++pattern && *pattern != ']'; + prev = *pattern) + if (*pattern == '-' + ? *string <= *++pattern && *string >= prev + : *string == *pattern) + matched = 1; + if (matched == reverse) + return 0; + continue; + } + + return *string == '\0'; +} + +static int +star (char *string, char *pattern) +{ + while (wild_match (string, pattern) == 0) + if (*++string == '\0') + return 0; + return 1; +} -- 2.44.0